你怎么用bash代表EOF?

时间:2009-01-21 02:20:24

标签: bash

我正在尝试做类似

的事情
read -d EOF stdin

for word in $stdin; do stuff; done

我希望将'EOF'替换为文件结尾字符的实际表示。

编辑:感谢您的回答,这确实是我想要做的。当我看到stdin=$(cat) lol

时,我实际上有一个facepalm时刻

只是为了踢,虽然你会如何匹配像C-d(或C-v M-v等)这样的东西,基本上只是一个与Control,Alt,Shift结合的角色,无论是什么样的bash?

5 个答案:

答案 0 :(得分:14)

真的没有文件结尾字符。按Ctrl-d或类似字符时,终端驱动程序通过返回无效值向读取应用程序发出已到达文件末尾的信号。当您到达文件末尾时,操作系统也会这样做。这是通过使用整数而不是字节来完成的(因此你的范围类似于-2 ^ 16 .. 2 ^ 16,而不仅仅是0..255)并返回超出范围的值 - 通常是{{1 }}。但是没有代表-1的角色,因为它的全部目的是一个角色。如果要读取从stdin到文件末尾的所有内容,请尝试

eof

然而,这将读取变量的整个标准输入。你可以使用数组只为一行分配内存,并使stdin=$(cat) for word in $stdin; do stuff; done 读取一行中的单词到该数组中:

read

答案 1 :(得分:10)

要查找控制角色是什么,请运行

$ cat | od -b
^D
0000000 004 012
0000002

我发出命令后键入 ^ V ^ D ,然后 RET 和另一个 ^ D (未引用的)结果是EOF是八进制004。

将该结果与read(1)结合使用:

$ read -d "$(echo -e '\004')" stdin
foo
bar quuz^Hx
^D
$ echo "$stdin"
foo
bar quux
$ for word in $stdin; do echo $word; done
foo
bar
quux

是的,我为退格键入了 ^ H 以查看read(1)是否做了正确的事情。确实如此。

答案 2 :(得分:7)

两件事......

EOF字符由C-d(或C-v C-d,如果你想输入它)表示,但要做你正在尝试的,最好这样做:

while read line; do stuff "${line}"; done

答案 3 :(得分:3)

litb&丹尼尔是对的,我会回答你的“Just for kick”问题: Bash(通常是任何命令行unix程序)只将字符视为字节。因此,您无法匹配Alt-v,您将匹配从用户解释这些按键的UI(伪tty)发送给您的任何字节。它甚至可以是unix信号,甚至不是字节。这取决于所使用的终端程序,用户设置和所有类型的东西,所以我建议你不要尝试匹配它们。

但是如果你知道你的终端发送C-v作为字节编号22(0x16),你可以使用以下内容:

if test "$char" = '^V'; then...

在您的编辑器下输入一个真正的^ V字符(在emacs下的C-q C-v,在xterm下的C-v C-v,......),而不是两个字符^和V

答案 4 :(得分:3)

我自己的终端驱动程序,当getc返回EOT时,fclose的stdout重新打开。这样,当读者的getc检测到空的写入队列并返回EOF(非char值)以表示它已关闭时,用户子例程(例如“cat”)可以移动参数并最终退出。因此,将EOF呈现为流条件或文件标记,而不是“char”范围内的值。