我试图让bash处理来自stdin的数据,但没有运气。我的意思是以下工作都不做:

echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=

echo "hello world" | read test; echo test=$test
test=

echo "hello world" | test=`cat`; echo test=$test
test=

我希望输出为test=hello world。我尝试在“$test”周围加上“”引号,但也不起作用。


当前回答

一个智能脚本,可以从PIPE和命令行参数读取数据:

#!/bin/bash
if [[ -p /dev/stdin ]]
    then
    PIPE=$(cat -)
    echo "PIPE=$PIPE"
fi
echo "ARGS=$@"

输出:

$ bash test arg1 arg2
ARGS=arg1 arg2

$ echo pipe_data1 | bash test arg1 arg2
PIPE=pipe_data1
ARGS=arg1 arg2

解释:当脚本通过管道接收任何数据时,/dev/stdin(或/proc/self/fd/0)将是到管道的符号链接。

/proc/self/fd/0 -> pipe:[155938]

如果不是,它将指向当前终端:

/proc/self/fd/0 -> /dev/pts/5

bash [[-p选项可以检查它是否是管道。

Cat -读取from stdin。

如果我们在没有stdin的情况下使用cat -,它将永远等待,这就是为什么我们把它放在If条件中。

其他回答

一个智能脚本,可以从PIPE和命令行参数读取数据:

#!/bin/bash
if [[ -p /dev/stdin ]]
    then
    PIPE=$(cat -)
    echo "PIPE=$PIPE"
fi
echo "ARGS=$@"

输出:

$ bash test arg1 arg2
ARGS=arg1 arg2

$ echo pipe_data1 | bash test arg1 arg2
PIPE=pipe_data1
ARGS=arg1 arg2

解释:当脚本通过管道接收任何数据时,/dev/stdin(或/proc/self/fd/0)将是到管道的符号链接。

/proc/self/fd/0 -> pipe:[155938]

如果不是,它将指向当前终端:

/proc/self/fd/0 -> /dev/pts/5

bash [[-p选项可以检查它是否是管道。

Cat -读取from stdin。

如果我们在没有stdin的情况下使用cat -,它将永远等待,这就是为什么我们把它放在If条件中。

从shell命令到bash变量的隐式管道的语法为

var=$(command)

or

var=`command`

在示例中,将数据输送到赋值语句,该语句不需要任何输入。

Read不会从管道中读取(或者可能因为管道创建了子shell而导致结果丢失)。然而,你可以在Bash中使用here字符串:

$ read a b c <<< $(echo 1 2 3)
$ echo $a $b $c
1 2 3

但是关于lastpipe的信息,请参阅@chepner的回答。

这是另一种选择

$ read test < <(echo hello world)

$ echo $test
hello world

将一些内容输出到包含赋值的表达式中就不是这样了。

相反,尝试:

test=$(echo "hello world"); echo test=$test