shell有一个很棒的功能,它可以在你使用“$ @”时保持变量扩展的参数引用,这样脚本就可以了:
for f in "$@"; do echo "$f"; done
使用参数调用时:
"with spaces" '$and $(metachars)'
将按字面打印:
with spaces
$and $(metachars)
这不是扩展引用字符串的正常行为,它似乎是“$ @”的特例。
有没有办法让其他变量出现这种行为?在我感兴趣的特定情况下,我希望安全在受限制的公钥条目中的$SSH_ORIGINAL_COMMAND
说明符中展开command=
,而不必担心参数中的空格,元字符等。
"$SSH_ORIGINAL_COMMAND"
会像"$*"
那样扩展,即一个天真的扩展,不会在单独的参数周围添加任何引号。
在这种情况下,获取env var SSH_ORIGINAL_COMMAND
时,“$ @”样式扩展所需的信息是不可用的?所以我需要说服sshd引用这些论点?
The answer to this question让我想知道它是否有可能。
答案 0 :(得分:4)
你可以得到类似的"引用的美元在"使用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