我试图让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 )
将工作太,但它将打开另一个新的子壳后管道,在哪里
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。
一个智能脚本,可以从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条件中。