0

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?

2
  • Are you delibarately using cat to input something and store into var ? Commented May 24, 2017 at 14:08
  • Can't you just shrink all of this to sed -n '3{p;q}' or similar? Commented May 24, 2017 at 14:25

5 Answers 5

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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'

Comments

0

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

Comments

0

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

#!/bin/bash

var=$(cat)

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

Comments

0

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 

5 Comments

That's a here-doc containing the echo "$var" line and delimited by end of file.
Accidental discovery. I always read about it but never took the pain to understand it :)
I mean, this will put the string echo | head -n 3 | tail -n 1 into var, which is hardly what you want.
I have tried this and this works.. not sure hw dat would end up in var..
How are you running it? I don't see a way in which it doesn't end up as the content of $var.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.