我有几行file
:
x 1
y 2
z 3 t
我需要将每一行作为参数传递给某个程序:
$ program "x 1" "y 2" "z 3 t"
我知道如何使用两个命令来做到这一点:
$ readarray -t a < file
$ program "${a[@]}"
我该如何使用一个命令?像这样:
$ program ??? file ???
答案 0 :(得分:1)
readarray
命令的(默认)选项表明您的file
项用换行符分隔。
因此,为了在 one 命令中实现所需的功能,您可以利用特殊的IFS
变量来对单词进行拆分。换行符(例如,参见this doc),并用无引号的命令替换来调用program
:
IFS=$'\n'; program $(cat file)
如@CharlesDuffy所建议:
您可能希望通过预先运行set -f
来禁用globbing,如果要将这些修改保留在本地,则可以将整个内容包含在一个子shell中:
( set -f; IFS=$'\n'; program $(cat file) )
为避免parens和/bin/cat
进程的性能损失,您可以改为:
( set -f; IFS=$'\n'; exec program $(<file) )
其中$(<file)
是Bash equivalent到$(cat file)
的位置(更快,因为它不需要分叉/bin/cat
),而exec使用由创建的子shell父母。
但是,请注意,如果exec
不是PATH中的真实程序,则program
技巧将无法使用(也就是说,如果exec: program: not found
program
只是脚本中定义的函数)。
答案 1 :(得分:0)
传递一组参数应该更有条理: 在此示例中,我正在寻找一个包含chk_disk_issue = something等的文件。因此,我通过读取作为参数传入的配置文件来设置值。
# -- 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
如果这些不是参数,则为脚本找到一种将其作为脚本内部数据读取并传递文件名的方法。