我正在为bash中的命令创建一个包装器脚本,我希望使用空格传递字符串参数,同时将其保存为bash文件中的字符串。
我已经看到很多问题,这些问题涉及将字符串作为一个项目传递给bash脚本,但不是如何维护字符串,以便在脚本中使用时保留字符串。
我还尝试了许多不同的方式来引用和转义字符,看看它是否有所不同
我的脚本如何布局的一个例子是
#!/usr/bin/env bash
exec my_program /path/to/code.py "${@}"
当我执行my_script -arg "A string"
时,所需的行为是将包装的命令作为my_program /path/to/code.py -arg "A string"
执行,而是以my_program /path/to/code.py -arg A string
的形式运行,导致error: unrecognized arguments: string
。
有没有什么方法可以确保,当传递一个字符串时,它会一直保持字符串?
最小,完整且可验证的示例:
巴士_strings.是
echo "${@}"
产量
$ bash bash_strings.sh --test "A String"
--test A String
你的bash_strings.sh
是有缺陷的,因为echo "$@"
抛弃数据(使./yourscript "hello world"
看起来与./yourscript "hello" "world"
相同)。要准确反映命令的参数列表,请使用printf %q
生成引用版本,如下所示:
#!/usr/bin/env bash
(( $# )) || exit
printf '%q ' "$@"; echo
...对于./bash_strings --test "A string"
,将作为输出发出:
--test 'A string'
......或者,可能是一个不同的语义相同的表示,例如:
--test A\ string
......无论哪种方式,都反映了原始引文真正通过了。
Bash会把报价拿出来。你必须再次插入它们。但是,如果您在包装器中转义引号,则每个参数都将在引号内解释:
exec my_program /path/to/code.py \"${@}\"
会变成
my_program /path/to/code.py "-arg A string"
你也不想要。
我认为最好的方法是,如果您的包装器适用于特定程序,请使用不同的标志执行case
,例如:
while getopts "arg:r:v" arg; do
case "$arg" in
arg)
exec my_program /path/to/code.py -arg $OPTARG
;;
r)
exec my_program /path/to/code.py -r $OPTARG
;;
v)
exec my_program /path/to/code.py -v $OPTARG
;;
esac
done
编辑为OP已编辑问题以保持清晰。
如果您将输入更改为:
bash bash_strings.sh --test "\"A String\""
对于这个具体的例子,它会起作用。 Bash正在某处删除引号。