我试图让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”周围加上“”引号,但也不起作用。
我认为您正在尝试编写一个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 ~ $
好了。
因为我上当了,我想留个便条。
我发现了这个线程,因为我必须重写一个旧的sh脚本
POSIX兼容。
这基本上意味着绕过POSIX引入的管道/子shell问题,重写如下代码:
some_command | read a b c
成:
read a b c << EOF
$(some_command)
EOF
代码是这样的:
some_command |
while read a b c; do
# something
done
成:
while read a b c; do
# something
done << EOF
$(some_command)
EOF
但后者在空输入时表现不一样。
使用旧的符号,while循环不会在空输入时输入,
但在POSIX符号中它是!
我认为这是由于EOF之前的换行,
这一点不容忽视。
POSIX代码的行为更像旧的符号
看起来是这样的:
while read a b c; do
case $a in ("") break; esac
# something
done << EOF
$(some_command)
EOF
在大多数情况下,这就足够了。
但不幸的是,这仍然不完全像以前的符号
如果some_command打印空行。
在旧的表示法中,执行while主体
在POSIX符号中,我们在主体前面中断。
解决这个问题的方法是这样的:
while read a b c; do
case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
# something
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF
如果你想读入大量数据并分别处理每一行,你可以使用这样的方法:
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编程语言》。
Use
IFS= read var << EOF
$(foo)
EOF
你可以像这样诱使read从管道中接受:
echo "hello world" | { read test; echo test=$test; }
或者写一个这样的函数:
read_from_pipe() { read "$@" <&0; }
但这没有意义——你的可变任务可能不会持久!管道可以生成子shell,其中环境是按值继承的,而不是按引用继承的。这就是为什么read不打扰管道的输入——它是未定义的。
仅供参考,http://www.etalabs.net/sh_tricks.html是一个漂亮的cruft收集必要的战斗奇怪和不兼容的伯恩炮弹,sh。