在 Bash 中包含多个带引号的 args 的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7454526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:02:53  来源:igfitidea点击:

Variable containing multiple args with quotes in Bash

bashvariablesescapingquotes

提问by hibou

I generate a bash variable containing all my args and those args contain spaces. When I launch a command with those args - eg. ls $args - quotes are not correctly interpreted. Here is an example - also creating and erasing needed files.

我生成了一个包含所有参数的 bash 变量,这些参数包含空格。当我使用这些参数启动命令时 - 例如。ls $args - 引号没有正确解释。这是一个示例 - 还创建和删除所需的文件。

#!/bin/bash
f1="file n1"
f2="file n2"
# create files
touch "$f1" "$f2"
# concatenate arguments
args="\"$f1\" \"$f2\""
# Print arguments, then launch 'ls' command
echo "arguments :" $args
ls $args
# delete files
rm "$f1" "$f2"

With that, I have some "no such file" errors for "file, n1", "fileand n2"

有了这个,我对"file, n1", "fileand n2"有一些 "no such file" 错误

回答by martin clayton

You might consider using an arrayfor the args, something like this:

您可能会考虑为 args使用数组,如下所示:

args=( "$f1" "$f2" )
ls "${args[@]}"

(The problem you're hitting at the moment is that once interpolation has happened there's no difference between intra- and inter- filename spaces.)

(您目前遇到的问题是,一旦发生插值,文件名空间内和文件名空间之间就没有区别。)

回答by Arran Cudbard-Bell

Use evalthis will first evaluate any expansions and quoting and then execute the resultant string as if it had been typed into the shell.

使用eval这将首先评估任何扩展和引用,然后执行结果字符串,就像它已被输入到 shell 中一样。

args="'$f1' '$f2'"
eval ls $args

eval will then be executing ls 'file n1' 'file n2'

然后将执行 eval ls 'file n1' 'file n2'

Had a very similar problem, trying to pass arguments in variables sourced from /etc/default/to start_stop_daemonin init scripts.

有一个非常类似的问题,试图通过争论从源变量/etc/default/,以start_stop_daemon在init脚本中。

回答by tripleee

Use setto set your variables as positional parameters; then quoting will be preserved if you refer to them via "$@"or "$1", "$2", etc. Make sure to use double quotes around your variable names.

使用set设置您的变量定位参数; 如果您通过"$@"或、 等引用它们"$1",则将保留引用"$2"。确保在变量名称周围使用双引号。

set -- "$f1" "$f2"
touch "$@"
ls "$@"
rm "$@"

回答by David Grayson

This is probably the worst answer, but you can change IFS. This is the "internal field separator" and is equal to space+tab+newline by default.

这可能是最糟糕的答案,但您可以更改IFS。这是“内部字段分隔符”,默认等于空格+制表符+换行符。

#!/bin/sh
IFS=,
MAR="-n,my file"
cat $MAR

The script above will run cat. The first argument will be -n(numbered lines) and the second argument will be my file.

上面的脚本将运行cat。第一个参数将是-n(编号的行),第二个参数将是my file

回答by bebbo

Here is my recipe to concat quoted arguments - mostly used to keep the script readable. But it's also comfortable to comment some arguments out easily:

这是我连接引用参数的方法 - 主要用于保持脚本的可读性。但是,轻松地注释掉一些论点也很舒服:

PARAM1="a param with white spaces"
PARAM2="some other funny param"
PARAM3="third spaced param"
#...

PARAMS=$PARAM1
PARAMS+='" "'
PARAMS+=$PARAM2
PARAMS+='" "'
PARAMS+=$PARAM3
#...

eval command '"'$PARAMS'"'