Fraggle
Fraggle

Reputation: 8727

Simple Unix redirection question: Pass lines in a file as command line arguments to a script

Ok, my Unix scripting skills are obviously really rusty. All I want to do is have a file with 4 arguments that I want passed to a script as if they came from the command line. But strangely doing this:

./myscript.sh < mycmds.txt

Doesn't seem to be working the way I expect. Contents of myscript.sh are:

cat >> out.txt <<EOF
$1 $2 $3 $4
EOF

So if I run myscript.sh from the command line like this: ./myscript.sh test1 test2 test3 test4 everything works great and I see test1 test2 test3 test4 show up in the out.txt file. But if I put test1 test2 test3 test4 as a line in a file called mycmds.txt and then run ./mysript.sh < mycmds.txt I just get an empty line in out.txt file.

So what am I doing wrong here? What is the proper way to store arguments in a file and pass them to a script so that they will be treated just as if they came from the command line?

Upvotes: 3

Views: 6972

Answers (3)

paxdiablo
paxdiablo

Reputation: 882078

That's because < is input redirection and sends that line in as standard input to the process, nothing at all to do with command line arguments.

You can do something like:

./myscript.sh $(cat mycmds.txt)

The $(xyz) construct runs xyz then uses its standard output to construct that part of the command. For example:

ls $(expr 1 + 3)

will attempt to give you a directoy listing for the file called 4, as follows.

First the command expr 1 + 3 is executed and the output is 4. This is then substituted in to the outer command to give you ls 4 and that is executed.

Upvotes: 1

Jens
Jens

Reputation: 72707

The subtlety you miss is that the standard input and positional parameters are not the same thing.

Standard input, which you can redirect with the '<', or even from another program with '|' is a sequence of bytes. A script can read stdin with, well, the read command.

Positional parameters are numbered 1 to N and hold the value of each argument. The shell refers to them as $1 to ${42} (if you gave that many).

Standard input and positional parameters are indepent of one another. You can have both, either, or none, depending how you call a program (and what that program expects):

  1. Both: grep -E pattern < file
  2. Just stdin: wc < file
  3. Just positional paramters: echo Here are five positional parameters
  4. Neither: ls

Upvotes: 0

Costi Ciudatu
Costi Ciudatu

Reputation: 38235

To make the content of mycmds.txt available as command line parameters, just inline the content when you call myscript.sh:

./myscript.sh $(< mycmds.txt)

Upvotes: 6

Related Questions