35

In a bash script I want to do the following:

script.sh < some_file

The some_file is a file that has 1 single line that I want to pass it as an argument to my bash script.sh. How can I do this?

0

4 Answers 4

43

Three variations:

  1. Pass the contents of the file on the command line, then use that in the script.
  2. Pass the filename of the file on the command line, then read from the file in the script.
  3. Pass the contents of the file on standard input, then read standard input in the script.

Passing the contents as a command line argument:

$ ./script.sh "$(<some_file)"

Inside the script:

some_data=$1

$1 will be the value of the first command line argument.

This would fail if you have too much data (the command that the shell would have to execute would grow too big).


Passing the filename:

$ ./script.sh some_file

Inside the script:

some_data=$(<"$1")

or

IFS= read -r some_data <"$1"

Connecting standard input to the file:

$ ./script.sh <some_file

Inside the script:

IFS= read -r some_data

The downside with this way of doing it is that the standard input of the script now is connected to some_file. It does however provide a lot of flexibility for the user of the script to pass the data on standard input from a file or from a pipeline.

12
cat some_file | ./script.sh `xargs` 
1
  • 1
    Somewhat overkill for a single line.
    – Kusalananda
    Commented Sep 20, 2017 at 9:23
3

To avoid worry about Bash shell quoting of the contents, use xargs to pass the whole file as-is via argument, including even a multi-line file:

cat input-file | xargs -0 -I XX mycommand arg1 --foo XX arg3

The XX is a placeholder I chose and could be anything as long as it doesn't appear anywhere in the command line except for where you want the input-file text to be placed.

-0 tells xargs to separate the input file by the null character so that line endings are not used as separators. This way the entire file gets passed in as a single argument (unless the file contains null characters which text files should not).

Since you have control over the script, why not pass the filename as an argument?

2

Using the read shell-builtin you can read data from stdin and store the read input to shell variables:

$ echo foo bar baz | read a b c
$ echo $a
foo
$ echo $b
bar
$ echo $c
baz

As you can see, read splits is input into fields. Where the input is split is determined by the $IFS variable (the Input Field Seperator). By setting $IFS to the empty value, input splitting is disabled and you can save a complete line to one variable:

$ echo foo bar baz | IFS= read foo
$ echo $foo
foo bar baz
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .