gpt4 book ai didi

bash - 从字符串中正确读取引用/转义的参数

转载 作者:太空宇宙 更新时间:2023-11-04 11:51:06 24 4
gpt4 key购买 nike

我在将参数传递给 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”周围没有引号是吗?

最佳答案

几句介绍

如果可能的话,不要使用 shell 引号字符串作为输入格式。

  • 很难一致地解析:不同的 shell 有不同的扩展,不同的非 shell 实现实现不同的子集(参见下面 shlexxargs 之间的增量)。
  • 很难以编程方式生成。 ksh 和 bash 有 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 更安全因为如果参数比可容纳的更多或更长,它会抛出错误,而不是将多余的参数作为单独的命令运行。


Python shlex -- 而不是 xargs -- 带有 bashisms

如果你需要比 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/56044544/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com