physio
physio

Reputation: 129

Bash script and manually running commands on the command line

I have the following simple bash script which takes input from stdin and prints the third line given as input.

#!/bin/bash

var=$(cat)

echo $var | head -n 3 | tail -n 1

The problem with this script is that it prints all the lines but here is the funny part, when I type the commands individually on the command line I am getting the expected result i.e. the third line. Why this anomaly? Am I doing something wrong here?

Upvotes: 0

Views: 185

Answers (5)

anubhava
anubhava

Reputation: 786021

You don't need $(cat) in your script. If script is reading data from stdin then just have this single line in your script:

head -n 3 | tail -n 1

And run it as:

bash myscript.sh < file.txt

This will print 3rd line from file.txt


PS: You can replace head + tail with this faster sed to print 3rd line from input:

sed '3q;d'

Upvotes: 1

Nahuel Fouilleul
Nahuel Fouilleul

Reputation: 19335

The aim of head -n 3 | tail -n 1 is to keep the third line into variable It will be more efficient to use read builtin

read
read
read var
echo "${var}"

Or to keep heading white-spaces

IFS= read

and not join lines ending with \ or not give special meaning to \

read -r

Upvotes: 1

Nikhil Fadnis
Nikhil Fadnis

Reputation: 797

var=$(cat) will not allow you to escape out of stdin mode. you need to specify the EOF for the script to understand to stop reading from stdin.

 read -d '' var << EOF
 echo "$var" | head -n 3 | tail -n 1 

Upvotes: 0

zezollo
zezollo

Reputation: 5027

This should do the trick, as far as I understand your question:

#!/bin/bash

var=$(cat)

echo "$var" | head -n 3 | tail -n 1

Upvotes: 0

tso
tso

Reputation: 4934

The shell is splitting the var variable so echo get multiple parameters. You need to quote your variable to prevent this to happen:

#!/bin/bash

var=$(cat)

echo "$var" | head -n 3 | tail -n 1

Upvotes: 0

Related Questions