Reputation: 551
I have file
with a few lines:
x 1
y 2
z 3 t
I need to pass each line as paramater to some program:
$ program "x 1" "y 2" "z 3 t"
I know how to do it with two commands:
$ readarray -t a < file
$ program "${a[@]}"
How can i do it with one command? Something like that:
$ program ??? file ???
Upvotes: 0
Views: 65
Reputation: 14723
The (default) options of your readarray
command indicate that your file
items are separated by newlines.
So in order to achieve what you want in one command, you can take advantage of the special IFS
variable to use word splitting w.r.t. newlines (see e.g. this doc) and call your program
with a non-quoted command substitution:
IFS=$'\n'; program $(cat file)
As suggested by @CharlesDuffy:
you may want to disable globbing by running beforehand set -f
, and if you want to keep these modifications local, you can enclose the whole in a subshell:
( set -f; IFS=$'\n'; program $(cat file) )
to avoid the performance penalty of the parens and of the /bin/cat
process, you can write instead:
( set -f; IFS=$'\n'; exec program $(<file) )
where $(<file)
is a Bash equivalent to to $(cat file)
(faster as it doesn't require forking /bin/cat
), and exec consumes the subshell created by the parens.
However, note that the exec
trick won't work and should be removed if program
is not a real program in the PATH (that is, you'll get exec: program: not found
if program
is just a function defined in your script).
Upvotes: 1
Reputation: 7327
Passing a set of params should be more organized : In this example case I'm looking for a file containing chk_disk_issue=something etc.. so I set the values by reading a config file which I pass in as a param.
# -- read specific variables from the config file (if found) --
if [ -f "${file}" ] ;then
while IFS= read -r line ;do
if ! [[ $line = *"#"* ]]; then
var="$(echo $line | cut -d'=' -f1)"
case "$var" in
chk_disk_issue)
chk_disk_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
;;
chk_mem_issue)
chk_mem_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
;;
chk_cpu_issue)
chk_cpu_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
;;
esac
fi
done < "${file}"
fi
if these are not params then find a way for your script to read them as data inside of the script and pass in the file name.
Upvotes: 0