linux - 为什么管道输出到 bash 函数不起作用

标签 linux bash shell unix pipe

对此有很多讨论: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

然后我们有:

总共 32 drwxr-xr-x 6 phil staff 204 Sep 11 21:18 。 drwx------+ 17 名菲尔员工 578 Sep 10 21:34 .. lrwxr-xr-x 1 菲尔员工 2 Sep 10 21:35 s1 -> t1 lrwxr-xr-x 1 菲尔员工 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

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

谢谢,

最佳答案

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

  • 命令行参数:$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" 带有引号,否则换行符将被损坏。

关于linux - 为什么管道输出到 bash 函数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52277395/

相关文章:

python - 如何将此 for 循环生成的列表列表写入文件(Python)?

linux - 为什么我的信号处理程序不工作?

linux - 如何使用 awk 和 bash 检查文本文件中的字段是否为空

shell - 用 sed 替换单个空格而不接触多个空格

regex - 删除 grep 输出中多余的引号

linux - 我想从另一个脚本运行一个脚本,使用相同版本的 perl,并将 IO 重新路由到类似终端的文本框

linux - Unix shell 目录历史

bash - 使用bash命令从远程服务器读取大文件的前n行

python提取特定帮助模块的信息

java - 通过 jdbc 运行 shell 命令