我试图让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”周围加上“”引号,但也不起作用。


当前回答

第一次尝试非常接近。这种变化应该是有效的:

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

输出为:

test = hello world

在管道后面需要用大括号括起要测试的赋值和回显。

如果没有大括号,test的赋值(在管道之后)在一个shell中,而echo "test=$test"在一个单独的shell中,该shell不知道该赋值。这就是为什么在输出中得到"test="而不是"test=hello world"。

其他回答

这个怎么样:

echo "hello world" | echo test=$(cat)

我不是Bash方面的专家,但我想知道为什么没有人提出这个建议:

stdin=$(cat)

echo "$stdin"

一行程序证明它对我有效:

$ fortune | eval 'stdin=$(cat); echo "$stdin"'

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

var=$(command)

or

var=`command`

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

我想要类似的东西——一个可以解析字符串的函数,可以作为参数或管道传递。

我提出了一个解决方案如下(工作作为#!/bin/sh和作为#!/bin/bash)

#!/bin/sh

set -eu

my_func() {
    local content=""
    
    # if the first param is an empty string or is not set
    if [ -z ${1+x} ]; then
 
        # read content from a pipe if passed or from a user input if not passed
        while read line; do content="${content}$line"; done < /dev/stdin

    # first param was set (it may be an empty string)
    else
        content="$1"
    fi

    echo "Content: '$content'"; 
}


printf "0. $(my_func "")\n"
printf "1. $(my_func "one")\n"
printf "2. $(echo "two" | my_func)\n"
printf "3. $(my_func)\n"
printf "End\n"

输出:

0. Content: ''
1. Content: 'one'
2. Content: 'two'
typed text
3. Content: 'typed text'
End

对于最后一种情况(3.),您需要键入,按enter和CTRL+D结束输入。

一个智能脚本,可以从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条件中。