Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.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
Arrays 使用管道运行bash数组_Arrays_Bash_Pipeline - Fatal编程技术网

Arrays 使用管道运行bash数组

Arrays 使用管道运行bash数组,arrays,bash,pipeline,Arrays,Bash,Pipeline,如何从包含管道的bash数组运行命令行 例如,我希望通过以下方式运行ls | grep x: $ declare -a pipeline $ pipeline=(ls) $ pipeline+=("|") $ pipeline+=(grep x) $ "${pipeline[@]}" 但我明白了: ls: cannot access |: No such file or directory ls: cannot access grep: No such file or directory ls

如何从包含管道的
bash
数组运行命令行

例如,我希望通过以下方式运行
ls | grep x

$ declare -a pipeline
$ pipeline=(ls)
$ pipeline+=("|")
$ pipeline+=(grep x)
$ "${pipeline[@]}"
但我明白了:

ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
ls: cannot access x: No such file or directory

关闭-只需添加
eval

$ eval ${pipeline[@]}
这对我很有用:

bash -c  "${pipeline[*]}"
简而言之:你不能(不写一些代码),这是一个特性,不是一个bug

如果您以一种安全的方式进行操作,那么您就是在保护您的数据不被解析为代码(语法)。然而,这里您明确想要的是将数据作为代码处理,但只能以受控的方式处理

您可以做的是迭代元素,如果它们不是管道,则使用
printf“%q'”$element“
获取一个带安全引号的字符串,如果它们是管道,则不替换它们

这样做之后,并且只有这样做之后,您才能安全地评估输出字符串

eval_args() {
  local outstr=''
  while (( $# )); do
    if [[ $1 = '|' ]]; then
      outstr+="| "
    else
      printf -v outstr '%s%q ' "$outstr" "$1"
    fi
    shift
  done
  eval "$outstr"
}
eval_args "${pipeline[@]}"

顺便说一下,不这样做安全多了。考虑这样一种情况,您正在处理一个文件列表,其中一个文件名为
|
;攻击者可以使用此策略注入代码。为前后数组使用单独的列表,或者只将管道的一侧作为数组并对另一侧进行硬编码,这是更好的做法。

但这非常脆弱且容易出错,因为空格、引号和星号等可以在多个阶段进行处理。这不是shell脚本的全部内容吗?;-)@CarlNorum不,shell脚本不是关于免费的安全漏洞。不管怎么说,如果你做得对的话就不会了。我想那张眨眼的脸就到此为止吧。OP的问题没有任何这些问题。你也可以写一个答案。@CarlNorum我正在写一个。构建和测试健壮的东西需要时间。尝试一些更有趣的东西。例如:
pipeline=(“cat”文件名加空格“|”tr'[a-z]'[a-z]')
;您给出的表单将
文件名
空格
视为
cat
@CharlesDuffy的三个不同参数,您的观点是正确的。话虽如此,OP似乎希望从命令行运行一些东西,并控制输入。不确定名称中带有空格的文件是否在UNIX上常见。总的来说,我认为您的
eval_args
函数可能是一个不错的选择,我将+1它。即使包含文本字符串
$(rm-rf/)
的文件名不常见,但您仍然不希望在出现这种情况时对其进行求值。数据丢失事件和安全漏洞希望是不常见的事件,但您不要因此而忽视其前驱体发生的可能性。+1,但建议不要编写这样的代码,这一点再强调也不过分。