【问题标题】:How to pass command line arguments with spaces through a variable in bash [duplicate]如何通过bash中的变量传递带有空格的命令行参数[重复]
【发布时间】:2017-06-25 23:19:17
【问题描述】:

我想要实现的是从文件中读取命令行参数并使用它们调用命令。所以基本上我需要通过 bash 变量传递参数。问题是某些参数中有空格。我该怎么做?

不工作的代码,来说明问题:

file.txt 内容(引号只是为了显示两个不同的参数):

"aaa bbb" "xxx yyy"

shell脚本:

ARGS=$(cat file.txt)
/some/command $ARGS

/some/command 应该接收两个参数:aaa bbbxxx yyy。我确实可以控制生成的 file.txt 和 shell 脚本本身。

【问题讨论】:

  • 我认为文件内容对正确答案有很大影响。您可以在 file.txt 中添加更多数据(即多行)吗?
  • 您能否澄清一下您是否打算将"aaa bbb" "xxx yyy" 用作传递给您的命令的一个参数(带有文字引号),或者这是否应该被解释为具有各自值的两个参数@987654327 @ 和 xxx yyy?
  • @GeorgeVasiliou 正如我所写的,我可以完全控制生成的文件和脚本。我可以给他们写任何东西。
  • @Fred 引用只是为了说明两个不同的论点。
  • 你是从一个错误的前提开始的,即这种类型的配置文件是个好主意;不是。

标签: bash shell


【解决方案1】:

如果您想对file.txt 中的每一行执行一次命令,因此每一行都是一个单独的参数集,您可以这样做:

xargs /some/command <file.txt

xargs 实用程序获取它在标准输入中接收到的每一行,并将其内容作为参数提供给被调用的命令。如果文件只包含一行,它将工作并只执行一次命令。

以下解决方案的作用相同,但也适用于函数:

while IFS= read -r line
do
  eval args=\("$line"\)
  command_or_function "${args[@]}"
done<file.txt

请注意这里使用eval,这意味着如果file.txt包含恶意内容,可能会导致任意代码执行。您必须 100% 确定文件中包含的数据是安全的。

这种技术的想法是将每一行分解为一个数组(一个数组元素是一个参数),然后使用数组扩展 ("${args[@]}") 扩展为其所有元素的列表,并正确引用 (扩展周围的引号在这里很重要)。

顺便说一句,eval 行可以替换为:

declare -a args=\($line\)

但是$line 仍然会扩展,所以这并不比eval 更安全。

【讨论】:

  • 更新修复了它干杯!但是这个琐碎的任务不需要eval,可以像我的回答一样简单地修复。
  • @Inian 请解释哪些报价被剥夺了?如果您正在谈论基于数组的解决方案,请尝试一下:数组拆分将遵循文件中的引用(例如,示例数据将创建一个包含两个元素的数组),并且数组扩展还将为命令产生两个参数.
  • 我的意思是xargs中的逻辑,试试xargs echo &lt; file.txt
  • @Fred 是的,readarray 现在可以正常工作,我对其进行了测试。您仍然可以通过使用declare -a args=\(......\) 来避免使用 eval 并避免恶意代码执行。我测试并得到相同的结果。
  • @Fred Welcome :-) 老实说,这是一个高评价的人在 SO (在不同的问题下)的提议,只是为了避免使用 eval 。我还尝试declare -a args +=\(...\) 附加数组,在我的测试中仍然可以正常工作。
【解决方案2】:

使用命令替换,将文件内容扩展为命令,

/some/command "$(<file.txt)"

举个例子,

cat file
"aaa bbb" "xxx yyy"

在上面使用printf 不正确cat 将产生

printf "%s\n" $(cat file)
"aaa
bbb"
"xxx
yyy"

在正确引用的情况下,参数会按原样发送而不会被拆分。

printf "%s\n" "$(<file)"
"aaa bbb" "xxx yyy"

【讨论】:

  • OP 想要传递包含空格的参数,但我认为他也想用引号将数据文件中的参数括起来(因此允许行上的许多参数)。因此,我的理解是双引号不是参数值的一部分,只是分隔符(就像在普通命令中一样)。您的方法将引号作为整行的一个大字符串的一部分传递,不涉及拆分。
  • @Fred:事实上he also wants to enclose arguments in the data file with quotes (therefore allowing many arguments on the line). 只是一个简单的假设,OP 从未建议过,请坚持足够简单的要求
  • @Fred:你能不能删除你的评论It does not really work
猜你喜欢
  • 2014-10-17
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2021-11-20
  • 1970-01-01
  • 2018-12-14
相关资源
最近更新 更多