这是我的问题的后续:当命令的参数带有空格或要扩展的内容时,如何编写 bash 函数来打印和运行命令 https://stackoverflow.com/q/71117953/4561887
假设我有这个函数来打印并运行存储在数组中的命令:
# Print and run the cmd stored in the passed-in array
print_and_run() {
echo "Running cmd: $*"
# run the command by calling all elements of the command array at once
"$@"
}
这工作正常:
cmd_array=(ls -a /)
print_and_run "${cmd_array[@]}"
但这不起作用:
cmd_array=(ls -a / | grep "home")
print_and_run "${cmd_array[@]}"
Error: syntax error near unexpected token `|'
:
eRCaGuy_hello_world/bash$ ./print_and_run.sh
./print_and_run.sh: line 55: syntax error near unexpected token `|'
./print_and_run.sh: line 55: `cmd_array=(ls -a / | grep "home")'
我怎样才能让这个概念与管道操作员一起工作(|
)在命令中?
如果你想处理一个只包含|
作为生成管道的指令,您可以这样做。我不推荐它 - 如果您不验证字符串中的变量不能仅包含单个管道字符,则意味着您存在安全风险 - 但这是可能的。
下面,我们创建一个随机的一次性"$pipe"
使攻击变得更加困难的印记。如果你不愿意这样做,那就改变[[ $arg = "$pipe" ]]
to [[ $arg = "|" ]]
.
# generate something random to make an attacker's job harder
pipe=$(uuidgen)
# use that randomly-generated sigil in place of | in our array
cmd_array=(
ls -a /
"$pipe" grep "home"
)
exec_array_pipe() {
local arg cmd_q
local -a cmd=( )
while (( $# )); do
arg=$1; shift
if [[ $arg = "$pipe" ]]; then
# log an eval-safe copy of what we're about to run
printf -v cmd_q '%q ' "${cmd[@]}"
echo "Starting pipeline component: $cmd_q" >&2
# Recurse into a new copy of ourselves as a child process
"${cmd[@]}" | exec_array_pipe "$@"
return
fi
cmd+=( "$arg" )
done
printf -v cmd_q '%q ' "${cmd[@]}"
echo "Starting pipeline component: $cmd_q" >&2
"${cmd[@]}"
}
exec_array_pipe "${cmd_array[@]}"
查看它在在线沙箱中运行:https://ideone.com/IWOTfO https://ideone.com/IWOTfO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)