如何通过bash中的变量传递带有空格的命令行参数 [英] How to pass command line arguments with spaces through a variable in bash
问题描述
我想要实现的是从文件中读取命令行参数,并使用它们来调用命令.所以本质上我需要通过bash变量传递参数.问题在于某些参数中有空格.我该怎么办?
What I'm trying to achieve is to read command line arguments from a file and invoke a command using them. So essentially I need to pass the arguments through a bash variable. The problem is that some arguments have spaces in them. How can I do that?
无法正常工作的代码,以说明问题:
Not working code, to illustrate the problem:
file.txt内容(引号只是为了显示两个不同的参数):
file.txt contents (quotes are there just to show two different arguments):
"aaa bbb" "xxx yyy"
shell脚本:
ARGS=$(cat file.txt)
/some/command $ARGS
/some/command
应该接收两个参数:aaa bbb
和xxx yyy
.我确实可以控制生成的file.txt和shell脚本本身.
/some/command
should receive two arguments: aaa bbb
and xxx yyy
. I do have control of generated file.txt and the shell script itself.
推荐答案
如果要对file.txt
中找到的每一行执行一次命令,因此每一行都是一个单独的参数集,则可以执行以下操作:>
If you want to execute your command once for each line found in file.txt
, so each line is a separate argument set, you can do this :
xargs /some/command <file.txt
xargs
实用程序采用标准输入接收的每一行,并将其内容用作要提供给所调用命令的参数.如果文件仅包含一行,它将起作用并且仅执行一次命令.
The xargs
utility takes each line it receives on standard input and uses its content as arguments to be provided to the command that is called. If the file contains only one line, it will work and execute the command only once.
以下解决方案具有相同功能,但也可以与功能一起使用:
The following solution does the same, but works with functions too:
while IFS= read -r line
do
eval args=\("$line"\)
command_or_function "${args[@]}"
done<file.txt
请注意,这使用了eval
,这意味着如果file.txt
包含恶意内容,则可能导致任意代码执行.您必须100%确保文件中包含的数据是安全的.
Please note that this uses eval
, which means that if file.txt
contains malicious content, arbitrary code execution could result. You must be 100% certain that the data contained in the file is safe.
使用这种技术的想法是,将每一行分解成一个数组(一个数组元素是一个参数),然后使用数组扩展("${args[@]}"
)扩展为所有其元素的列表,并用引号引起来(扩展周围的引号在这里很重要.)
The idea with this technique is that you explode each line into an array (one array element is one argument), and then use an array expansion ("${args[@]}"
) that expands to a list of all its elements, properly quoted (the quotes around the expansion are important here).
顺便说一句,eval
行可以替换为:
As an aside, the eval
line could be replaced with :
declare -a args=\($line\)
但是$line
仍会扩展,因此这并不比eval
更安全.
But $line
still gets expanded, so this is no safer than eval
.
这篇关于如何通过bash中的变量传递带有空格的命令行参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!