我有一个bash脚本,我希望从文件中读取它以获取它的参数集。基本上我的脚本在位置上读取参数($1
,$2
,$3
等。)
while test $# -gt 0; do
case $1 in
-h | --help)
echo "Help cruft"
exit 0
;;
esac
shift
done
我希望其中一个选项可能是一个读取参数的配置文件(简单易用 config ),所以我希望set --
命令可以正常工作({{1过度争论)。但是,由于它们是在文件中定义的,我必须将其读入并使用--
来传递它们:
xargs
麻烦在于xargs在-c | --config)
cat $2 | xargs set --
continue
;;
上骚扰,所以我不知道如何做到这一点。
注意:我意识到我可以使用--
并设置变量;可能是最后的选择。我想知道我是否可以像上面那样做并简化文档。
简化的示例脚本:
source config_file
答案 0 :(得分:4)
xargs
无法执行set
,因为:
set
是内置的shell,而不是外部命令。 xargs
只知道如何执行命令。 (一些具有相同名称的shell内置阴影命令,例如printf
,true
和[
。所以xargs
可以执行这些命令,但语义可能不会与内置相同。)
即使xargs
可以执行set
,它也无效,因为xargs
不会在shell的环境中运行; xargs
执行的每个命令都是一个单独的过程。因此,如果您这样做,您将不会收到任何错误:
echo a b c | xargs bash -c 'set -- "${@}"' _
但它也不会做任何有用的事情。 (用set
替换echo
,你会发现它确实调用了命令。)
首先,您需要回答这个问题:在文件中包含参数意味着什么?它们是单独的以空格分隔的单词,没有机制在任何参数中包含空格吗? (这也是xargs
在默认模式下工作所必需的,所以这不是一个完全不合理的假设,尽管它几乎肯定会让你在某些时候遇到麻烦。)
在这种情况下,您根本不需要xargs
;你可以使用命令替换:
set -- $(<file)
虽然这样可以正常工作,但这不会:
echo a b c | set -- $(</dev/stdin)
因为管道(由 | 运算符创建)导致任一侧的进程在子shell中运行,因此set
不会修改当前shell的环境变量。
假设每个参数都在文件的一行中,这样就可以在参数中包含空格,但不能在换行符中包含空格。然后我们可以使用有用的mapfile
内置函数将参数读入数组,并从数组中设置位置参数。 (或者直接使用数组,但这是一个不同的问题。)
mapfile -t args < file
set -- "${args[@]}"
再次注意管道mapfile
;它不起作用,原因与它不适用于set
。