我在将参数传递给Bash脚本中的命令时遇到问题。
poc.sh:
#!/bin/bash
ARGS='"hi there" test'
./swap ${ARGS}
交换:
#!/bin/sh
echo "${2}" "${1}"
当前输出为:
there" "hi
仅更改poc.sh(因为我相信swap可以正确执行我想要的操作),如何使poc.sh传递“hi there”并作为两个参数进行测试,而“hi there”周围没有引号?
最佳答案
几个入门词
如果可能的话,请不要使用用引号引起来的字符串作为输入格式。
shlex
和xargs
之间的增量)。 printf '%q'
,它将生成一个用shell引用的字符串,该字符串带有任意变量的内容,但是在POSIX sh标准中不存在与此等效的字符串。 eval
,它具有相当大的安全性问题。 以NUL分隔的流是一种更好的做法,因为它们可以准确地表示任何可能的shell数组或参数列表,而不会产生任何歧义。
xargs,带有bashisms
如果要使用 shell 程序引号从人工生成的输入源获取参数列表,则可以考虑使用
xargs
对其进行解析。考虑:array=( )
while IFS= read -r -d ''; do
array+=( "$REPLY" )
done < <(xargs printf '%s\0' <<<"$ARGS")
swap "${array[@]}"
...会将解析后的
$ARGS
内容放入数组array
中。如果您想从文件中读取,请用<filename
代替<<<"$ARGS"
。xargs,符合POSIX
如果您试图编写与POSIX sh兼容的代码,这将变得更加棘手。 (为了降低复杂性,我将在此处假设文件输入):
# This does not work with entries containing literal newlines; you need bash for that.
run_with_args() {
while IFS= read -r entry; do
set -- "$@" "$entry"
done
"$@"
}
xargs printf '%s\n' <argfile | run_with_args ./swap
这些方法比运行
xargs ./swap <argfile
更安全,因为如果存在更多或更长的参数(而不是将多余的参数作为单独的命令运行),则会引发错误。带有shash的Python shlex-而不是xargs-
如果您需要比
xargs
实现更准确的POSIX sh解析,请考虑改用Python shlex
模块:shlex_split() {
python -c '
import shlex, sys
for item in shlex.split(sys.stdin.read()):
sys.stdout.write(item + "\0")
'
}
while IFS= read -r -d ''; do
array+=( "$REPLY" )
done < <(shlex_split <<<"$ARGS")
关于bash - 从字符串中正确读取带引号/转义的参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26067249/