3

I wrote a script, including this loop:

#!/bin/bash

cat "$1" | while read -r line; do
  echo "$line"; sleep 2;
done

A shellcheck run put out the following message:

SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.

I changed the script to:

#!/bin/bash

cmd < "$1" | while read -r line; do
  echo "$line"; sleep 2;
done

but now bash exits with:

cmd: command not found

what have I done wrong?

8
  • 5
    cmd is a placeholder for the thing you're really running. In this case, that's the while loop. Commented Jul 23, 2017 at 21:26
  • So, if you were running cat foo | awk, it would be telling you to run awk <foo or awk foo -- the cmd would be awk. Commented Jul 23, 2017 at 21:27
  • IMHO the tool is giving you bad advice here, because bash won't actually let you write <filename while ...; I'm not sure if while ... done <filename works, but for a long command it's not that readable to push the input filename all the way to the end. It's a matter of opinion, I guess, but if cat keeps the pipeline in order, that's a big plus point in my book. Commented Jul 23, 2017 at 21:32
  • Thank you @IMSoP I was just thinking, also for me as a beginner the cmd < file | makes it look like cmd should just replace cat. But that means that my first example is not bad programming practise from your point of view. Commented Jul 23, 2017 at 21:41
  • A smarter tool, or a smarter shell programmer, might suggest a way to structure the whole line without the while read, but it's a pretty convenient idiom. Commented Jul 23, 2017 at 21:45

2 Answers 2

7

Your cmd is the whole while cond; do ... done compound statement and in this case the redirection needs to come at the end:

while read -r line; do
  echo "$line"; sleep 0.2
done < "$1"
Sign up to request clarification or add additional context in comments.

2 Comments

nice one, thank you! do you know what the 'cmd' stands for?
cmd can mean any command such as ps or netstat. If you wanted to process this in your loop, you would then do netstat | while read -r ....
3

Remove the | and have the end line as :

 done < "$1"

1 Comment

<"$1", rather. << would be starting a heredoc.

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.