我有以下脚本。它从 passwd 打印所有第一个字符到控制台,但我的期望是只获得一个字符,然后程序终止。
#!/bin/sh
cat /etc/passwd |
while read -r line
do
echo ${line} |
grep -o . |
while read char
do
echo ${char}
exit 1
done
done
实际输出:
r
b
d
a
(etc)
预期输出:
r
答案1
大多数类似 Bourne 的 shell,除了zsh
在ksh
子 shell 中运行管道的每个部分。假设您不使用zsh
or ksh
,那么在您的脚本中, pipiline 的最后一部分在子 shell 中运行,因此exit
退出该子 shell 而不是当前 shell。
zsh
您将在或中得到所需的输出ksh
。
无论如何,这些代码有很多缺陷:
如果您想要的只是获取文件中的第一个字符:
dd bs=1 count=1 if=/etc/passwd 2>/dev/null
或使用 GNU dd
:
dd status=none bs=1 count=1 if=/etc/passwd
它仅适用于 ASCII 字符。对于多字节字符:
LC_ALL=en_US.utf8 awk '{print substr($0,1,1);exit}'
更改LC_ALL
为您的文本所属的区域设置。
答案2
管道创建子壳。 shell 内置命令exit
终止 shell。导致您的情况出现意外行为:
> exit | exit | echo wow
wow
我建议看看管道中的部分man bash
。还看看help exit
。