bash:如何打印和运行其中包含管道运算符|的cmd数组 [英] Bash: how to print and run a cmd array which has the pipe operator, |, in it

查看:19
本文介绍了bash:如何打印和运行其中包含管道运算符|的cmd数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我这里问题的后续问题:How to write bash function to print and run command when the command has arguments with spaces or things to be expanded

假设我有以下函数来打印并运行存储在数组中的命令:

# 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[@]}"

错误: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")'

如何使此概念与命令中的管道运算符(|)一起使用?

推荐答案

如果要将仅包含|的数组元素视为生成管道的指令,则可以这样做。我不建议使用--这意味着如果您不验证字符串中的变量不能只由单个管道字符组成,就会有安全风险--但这是可能的。

下面,我们创建了一个随机单次使用信号,以使攻击更加困难。如果您不愿意这样做,请将[[ $arg = "$pipe" ]]更改为[[ $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

的在线沙箱中运行

这篇关于bash:如何打印和运行其中包含管道运算符|的cmd数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆