在 case 语句中使用 xargs

在 case 语句中使用 xargs

我想将长命令的输出(不能放在里面$())传输到 case 语句,所以我xargs像这样使用

echo "this" | xargs -I{} case {} in; this) echo "is a test";; esac

这不起作用,我收到错误

zsh: parse error near `)'

而以下运行没有问题

case "this" in; this) echo "is a test";; esac

我该如何解决?

答案1

case...in...esacsh类似语言的构造,因此xargs(来自 shell 的单独命令,而不是 shell 构造)需要为此调用 shell:

echo this | xargs -I'{}' sh -c '
  case $1 in
    (this) echo "is a test";;
  esac' sh '{}'

在任何情况下,您需要确保{}(在引号和空格处理后最终会扩展为xargs每行的内容)不会在代码内联脚本的参数sh(或任何解释器的代码参数,不仅仅是 sh ),否则将使其成为代码注入漏洞。

相反,在这里,{}被作为参数传递给内联脚本(在脚本中使用 检索$1),因此它无法被解释为 shell 代码。

如果您想case在当前(zsh此处)shell 中的命令输出的每一行上运行一个构造(xargs -I'{}'顺便说一下,只有这些行不包含反斜杠、单引号、双引号并且不以空格),你可以这样做:

while IFS= read <&3 -r line; do
  case $line in
    (this) ...;;
  esac 3<&-
done 3< <(a-command)

或者

for line (${(f)"$(a-command)"}) case $line in
  (this) ...;;
esac

(那个跳过空行)。

答案2

我原以为问题是因为case语句是跨多行构建的。你可能会像这样获得更多成功:

yourcommand | while read LINE ; do
  case "$LINE" in; this) echo "is a test";; esac
done

相关内容