如何通过bash中的变量传递带有空格的命令行参数 [英] How to pass command line arguments with spaces through a variable in bash

查看:413
本文介绍了如何通过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 bbbxxx 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆