【问题标题】:why pipe output into a bash function does not work为什么管道输出到 bash 函数不起作用
【发布时间】:2019-02-16 01:05:22
【问题描述】:

对此有很多讨论:Pipe output to bash function

我只想知道为什么:

  #bin/sh
  function myfunc () {
      echo $1
  }

  ls -la | myfunc

将给出空行。请问为什么我们的ls 的输出不被视为$1 作为函数?这背后的机制是什么?

如果我们尝试:

  #bin/sh
  function myfunc () {
      i=${*:-$(</dev/stdin)}
      echo $i
  }

  ls -la | myfunc

那么我们有:

total 32 drwxr-xr-x 6 phil staff 204 Sep 11 21:18 . drwx------+ 17 phil staff 578 Sep 10 21:34 .. lrwxr-xr-x 1 phil staff 2 Sep 10 21:35 s1 -> t1 lrwxr-xr-x 1 phil staff 2 Sep 10 21:35 s2 -> t2 lrwxr-xr-x 1 phil staff 2 Sep 10 21:35 s3 -> t3 -rwxr-xr-x 1 phil staff 96 Sep 11 21:39 test.sh

不保留ls -la 的实际格式(带有\n)。

将命令输出作为参数传递给函数的正确/建议方法是什么?

谢谢

更新 +John Kugelman

  #bin/sh
  function myfunc () {
    cat | grep "\->"  | while read line
    do
        echo $line
    done


    cat | grep "\->"  | while read line
    do
        echo "dummy"
    done
      }

  ls -la | myfunc

这只会打印一次。如果我们想使用两次结果怎么办(可能将其存储为变量?)

谢谢,

【问题讨论】:

  • 在第二个例子中,如果你想保持 ls 的格式,你可以使用 echo "$1"
  • +Gianluca Mereu 不,我不认为我会工作。作为第一个示例,它将得到空输出。

标签: linux bash shell unix pipe


【解决方案1】:

函数接收输入有两种不同的方式:

  • 命令行参数:$1$2
  • 标准输入。

当您将输出从一个命令传递到另一个命令时,它会在标准输入上接收,而不是作为参数。要阅读它,您可以执行以下操作之一:

myfunc() {
    cat
}

myfunc() {
    local line
    while IFS= read -r line; do
        printf '%s\n' "$line"
    done
}
ls -la | myfunc

如果您想保留您的函数并希望设置 $1,您需要从管道更改为命令替换。

myfunc() {
    echo "$1"
}
myfunc "$(ls -la)"

注意双引号的大量使用。确保在 echo "$1" 中加上引号,否则换行符会被破坏。

【讨论】:

  • 感谢您的回复。对于cat 之一,我可以问为什么我们不能猫两次?如果我们想重用这段代码怎么办? (我会在问题描述中再次添加代码详细信息。)
  • 标准输入只能读取一次。如果要处理两次,则需要将其保存在变量或临时文件中。最佳做法是一次性完成所有操作,因此您不必保存它。我会说这是一个新问题,而不是更新这个问题。如果您准确地发布您正在尝试做的事情,这将有所帮助,因此我们可以建议将两个循环合并为一个的最佳方法。
猜你喜欢
  • 2012-07-12
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
相关资源
最近更新 更多