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


当前回答

Bash 4.2引入了lastpipe选项,通过在当前shell(而不是子shell)中的管道中执行最后一条命令,允许代码按编写的方式工作。

shopt -s lastpipe
echo "hello world" | read test; echo test=$test

其他回答

以下代码:

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

将工作太,但它将打开另一个新的子壳后管道,在哪里

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

不会的。


我必须禁用作业控制来使用chepnars的方法(我从终端运行这个命令):

set +m;shopt -s lastpipe
echo "hello world" | read test; echo test=$test
echo "hello world" | test="$(</dev/stdin)"; echo test=$test

Bash手册说:

lastpipe 如果设置了,并且作业控制不处于活动状态,shell将运行最后一条命令 没有在当前shell的后台执行的管道 环境。

注意:在非交互式shell中,作业控制默认是关闭的,因此在脚本中不需要set +m。

如果你想读入大量数据并分别处理每一行,你可以使用这样的方法:

cat myFile | while read x ; do echo $x ; done

如果你想把这些行分成多个单词,你可以使用多个变量来代替x,就像这样:

cat myFile | while read x y ; do echo $y $x ; done

另外:

while read x y ; do echo $y $x ; done < myFile

但是一旦你开始想要做一些真正聪明的事情,你最好选择一些脚本语言,比如perl,你可以尝试这样的事情:

perl -ane 'print "$F[0]\n"' < myFile

使用perl(或者我猜这些语言中的任何一种)有一个相当陡峭的学习曲线,但如果您想做任何事情,而不是最简单的脚本,从长远来看,您会发现它要容易得多。我推荐《Perl烹饪书》,当然还有Larry Wall等人写的《Perl编程语言》。

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

stdin=$(cat)

echo "$stdin"

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

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

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

var=$(command)

or

var=`command`

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

我认为您正在尝试编写一个shell脚本,可以从stdin输入。 但是当您尝试内联执行时,您在尝试创建test=变量时迷失了方向。 我认为内联执行它没有多大意义,这就是为什么它不能以您期望的方式工作的原因。

我试着减少

$( ... | head -n $X | tail -n 1 )

从不同的输入中得到特定的一行。 所以我可以输入…

cat program_file.c | line 34

所以我需要一个小shell程序能够从stdin读取。就像你一样。

22:14 ~ $ cat ~/bin/line 
#!/bin/sh

if [ $# -ne 1 ]; then echo enter a line number to display; exit; fi
cat | head -n $1 | tail -n 1
22:16 ~ $ 

好了。