1

I would like to know if I can write a shell script that accepts two arguments simultaneously, one from a file and the another one from stdin. Could you give some example please?.

I trying

while read line
   do
   echo "$line"
done < "${1}" < "{/dev/stdin}"

But this does not work.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Juan
  • 2,073
  • 3
  • 22
  • 37
  • What does "an argument from a file and from stdin" mean? You mean reading the data from a file passed as argument? – m0skit0 Oct 29 '17 at 02:01
  • 1
    Interleaving the content (one line from the file, one from stdin, switching back and forth)? Concatenating them? Be more specific -- we *probably* have a duplicate, once enough details are given. – Charles Duffy Oct 29 '17 at 03:29

2 Answers2

2

You can use cat - or cat /dev/stdin:

while read line; do
  # your code
done < <(cat "$1" -)

or

while read line; do
  # your code
done < <(cat "$1" /dev/stdin)

or, if you want to read from all files passed through command line as well as stdin, you could do this:

while read line; do
  # your code
done < <(cat "$@" /dev/stdin)

See also:

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • I need that bash script accepts the two arguments simultaneously. I used to second example by doesnot work. I created test.txt and then I make bash myprogram.sh test.txt anything. But I only get the content from the file and not from stdin (anything) – Juan Oct 29 '17 at 02:29
  • @Juan what is anything? you want `stdin` literal to be inferred as stdin? – Jason Hu Oct 29 '17 at 02:45
  • Updated the answer to take care of all the arguments (file names) passed through command line. – codeforester Oct 29 '17 at 03:01
  • 1
    @Juan, ...also, "does not work" is simply not an adequate error report. Some of the reasons this might not work could relate to execution with the wrong shell (`sh` does not support process substitution syntax), or a typo or syntax error on entry. The comment given above is not sufficient to diagnose any of those cases -- and to be clear, the code given here *does* work when properly and correctly deployed. – Charles Duffy Oct 29 '17 at 17:57
  • @codeforester how this code < <(cat "$1" -) work?. <(cat "$1" -) is a redirect to stdin? why a blank space? – Juan Oct 31 '17 at 09:33
  • `-` is interpreted as stdin by many Unix commands, including `cat`. See this post: https://stackoverflow.com/questions/8045479/whats-the-magic-of-a-dash-in-command-line-parameters – codeforester Oct 31 '17 at 15:38
0

This topic seems to be helpful here:

{ cat $1; cat; } | while read line
   do
   echo "$line"
done

Or just

cat $1
cat

if all you're doing is printing the content

tkausl
  • 13,686
  • 2
  • 33
  • 50
  • 1
    `cat "$1"`, you mean. Otherwise a filename with a space won't be usable. And you only need one instance of `cat`, as stdin can be referred to as `-`, as follows: `cat "$1" -` – Charles Duffy Oct 29 '17 at 03:29
  • 1
    BTW, I'd suggest `done < <(cat "$1" -)` rather than `cat "$1" - | while` to avoid [BashFAQ #24](http://mywiki.wooledge.org/BashFAQ/024). – Charles Duffy Oct 29 '17 at 03:31