Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 为其他变量扩展获取美元报价(“$@”)行为?_Bash_Ssh_Arguments_Sh - Fatal编程技术网

Bash 为其他变量扩展获取美元报价(“$@”)行为?

Bash 为其他变量扩展获取美元报价(“$@”)行为?,bash,ssh,arguments,sh,Bash,Ssh,Arguments,Sh,shell有一个很好的特性,当您使用“$@”时,它将在变量扩展中保留参数引号,这样脚本: for f in "$@"; do echo "$f"; done 使用参数调用时: "with spaces" '$and $(metachars)' 将按字面意思打印: with spaces $and $(metachars) 这不是带引号字符串扩展的正常行为,它似乎是“$@”的一个特例 对于其他变量,有没有办法得到这种行为?在我感兴趣的特定情况下,我希望在受限公钥项中的命令=说明符中安全地扩展

shell有一个很好的特性,当您使用“$@”时,它将在变量扩展中保留参数引号,这样脚本:

for f in "$@"; do echo "$f"; done
使用参数调用时:

"with spaces" '$and $(metachars)'
将按字面意思打印:

with spaces
$and $(metachars)
这不是带引号字符串扩展的正常行为,它似乎是“$@”的一个特例

对于其他变量,有没有办法得到这种行为?在我感兴趣的特定情况下,我希望在受限公钥项中的
命令=
说明符中安全地扩展
$SSH\u ORIGINAL\u命令
,而不必担心参数中的空格、元字符等

“$SSH\u ORIGINAL\u命令”
“$*”
那样展开,也就是说,一个简单的展开,不在单独的参数周围添加任何引号

在这种情况下,当shell获取env var
SSH_ORIGINAL_命令时,“$@”样式扩展所需的信息是否对shell不可用?所以我需要说服sshd引用这些论点

让我想知道这是否可能。

您可以使用
“${YOUR_ARRAY_HERE[@]}”语法获得任意数组的类似“quoted dollar at”行为。当然,这不是完整的答案,因为您仍然需要根据引号将字符串拆分为多个数组元素

一种想法是使用
bash-x
,它呈现扩展的输出,但只有在您实际运行命令的情况下;它不适用于
-n
,这会阻止您实际执行相关命令。同样,您可以使用
eval
bash-c
以及
set--
来管理引号删除,在外壳上执行扩展,在外壳上执行引号删除,但要防止执行任意代码,这将是极其困难的

作为结束运行,请改用
xargs
。这是一个非常不完美的解决方案,因为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

克雷格,我相信你遇到的问题是一个分裂的问题。虽然暴力解决方案可能涉及设置
IFS
来控制分裂,但我不太清楚到底是什么原因无法提供任何类型的答案。在您试图在命令=
中获取
$SSH\u ORIGINAL\u命令时,
$SSH\u ORIGINAL\u命令的内容是什么?是什么导致了
命令=
公钥条目?我认为问题在于所需的信息在到达bash之前就丢失了。sshd必须注入一个bash数组,而不仅仅是提供一个平面字符串的环境变量。或者它必须预先引用env变量的内容。我将在稍后进行编辑和跟踪。这就是促使我想到
IFS
的原因。假设您有一个
$SSH_ORIGINAL_命令
,它包含“-x-p portno other stuff”,出于某种原因,它不适用于
命令=
。如果只有部分命令正确到达
command=
,则可以将
IFS=$'\n'
设置为仅在换行时中断,并确保
command=
$SSH\u原始\u命令
接收总数。我不确定这是否符合实际情况,但这正是我从描述中得到的。这救了我的命
COMMAND_ARRAY[0]: foo
COMMAND_ARRAY[1]: bar  baz
COMMAND_ARRAY[2]: $quux