shell 有一个很棒的特性,当你使用“$@”时,它会在变量扩展中保留参数引用,这样脚本:
for f in "$@"; do echo "$f"; done
当带参数调用时:
"with spaces" '$and $(metachars)'
将按字面意思打印:
with spaces
$and $(metachars)
这不是引号字符串扩展的正常行为,它似乎是“$@”的特例。
有什么方法可以让其他变量有这种行为吗?在我感兴趣的特定情况下,我想安全地在受限公钥条目的 command=
说明符中扩展 $SSH_ORIGINAL_COMMAND
,无需担心参数、元字符等中的空格。
"$SSH_ORIGINAL_COMMAND"
像 "$*"
那样扩展,即不在单独的参数周围添加任何引号的简单扩展。
在这种情况下,shell 获取环境变量 SSH_ORIGINAL_COMMAND
时,“$@”样式扩展所需的信息是否根本不可用?所以我反而需要说服 sshd 引用参数?
The answer to this question让我想知道这是否可能。
最佳答案
对于 bash arrays,您可以使用 "${YOUR_ARRAY_HERE[@]}"
语法为任意数组获得类似的“引用美元”行为.当然,这不是完整的答案,因为您仍然需要根据引号将字符串分成多个数组元素。
一个想法是使用 bash -x
,它会呈现扩展输出,但前提是您实际运行该命令;它不适用于 -n
,这会阻止您实际执行相关命令。同样,您可以使用 eval
或 bash -c
以及 set --
来管理引用删除、对外壳执行扩展和引用删除在内壳上,但这将非常难以防止执行任意代码。
作为结束运行,请改用 xargs
。 xargs handles single and double quotes.这是一个非常不完美的解决方案,因为 xargs 处理反斜杠转义字符的方式与 bash 非常不同,并且完全无法处理分号等,但如果您的输入相对可预测,它会帮助您解决大部分问题那里没有强制你写一个完整的 shell 解析器。
SSH_ORIGINAL_COMMAND='foo "bar baz" $quux'
# Build out the parsed array.
# Bash 4 users may be able to do this with readarray or mapfile instead.
# You may also choose to null-terminate if newlines matter.
COMMAND_ARRAY=()
while read line; do
COMMAND_ARRAY+=("$line")
done < <(xargs -n 1 <<< "$SSH_ORIGINAL_COMMAND")
# Demonstrate working with the array.
N=0
for arg in "${COMMAND_ARRAY[@]}"; do
echo "COMMAND_ARRAY[$N]: $arg"
((N++))
done
输出:
COMMAND_ARRAY[0]: foo
COMMAND_ARRAY[1]: bar baz
COMMAND_ARRAY[2]: $quux
关于bash - 获取其他变量扩展的 quoted-dollar-at ( "$@") 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24624291/