3

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?

3 Answers 3

6

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

3 Comments

Ooo.. I like the looks of $(< file). +1
Thanks, this seems clean and simple and works. Not sure why the $ is not mentioned more when I google "input redirection unix", but maybe its a semantics thing. Anyway thanks.
From the bash manual: "The command substitution $(cat file) can be replaced by the equivalent but faster $(< file)". It has little to do with input redirection, so don't think of it as some fancy form of the < file.
1

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.

1 Comment

Thanks. I choose a different but similar answer. I guess I'm sort of confused why < doesn't pass the contents of the file as if they were typed at the command line. I thought that was the point. Obviously I'm missing some subtlety here and the use of $ is required.
0

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

Comments

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.