您将如何在 bash 中表示 EOF?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/463913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How would you represent EOF in bash?
提问by user50264
I'm trying to do something like
我正在尝试做类似的事情
read -d EOF stdin
for word in $stdin; do stuff; done
where I want to replace 'EOF' for an actual representation of the end of file character.
我想用“EOF”替换文件结尾字符的实际表示。
Edit:Thanks for the answers, that was indeed what I was trying to do. I actually had a facepalm moment when I saw stdin=$(cat)
lol
编辑:感谢您的回答,这确实是我想要做的。当我看到stdin=$(cat)
lol时,我实际上有一个捂脸的时刻
Just for kicks though how would you go about matching something like a C-d (or C-v M-v etc), basically just a character combined with Control, Alt, Shift, whatever in bash?
只是为了踢球,尽管您将如何匹配诸如 Cd(或 Cv Mv 等)之类的东西,基本上只是一个与 Control、Alt、Shift 组合的字符,无论是 bash 中的什么?
回答by Johannes Schaub - litb
There isn't an end-of-file character really. When you press Ctrl-d or similar characters, the terminal driver signals to the reading application that the end of file has been reached, by returning an invalid value. The same is done by the operation system, when you have reached the end of the file. This is done by using an integer instead of a byte (so you have range similar to -2^16 .. 2^16, instead of only 0..255) and returning an out-of-range value - usually -1
. But there is no character that would represent eof
, because its whole purpose is to be nota character. If you want to read everything from stdin, up until the end of file, try
真的没有文件结束符。当您按 Ctrl-d 或类似字符时,终端驱动程序会通过返回无效值向读取应用程序发出信号,表明已到达文件末尾。当您到达文件末尾时,操作系统也会这样做。这是通过使用整数而不是字节来完成的(因此您的范围类似于 -2^16 .. 2^16,而不是仅 0..255)并返回超出范围的值 - 通常为-1
. 但是没有可以代表 的字符eof
,因为它的全部目的是不是一个字符。如果你想从 stdin 中读取所有内容,直到文件末尾,请尝试
stdin=$(cat)
for word in $stdin; do stuff; done
That will however read the whole standard input into the variable. You can get away with only allocating memory for one line using an array, and make read
read words of a line into that array:
然而,这会将整个标准输入读入变量。您可以使用数组只为一行分配内存,并将read
一行的读取字放入该数组中:
while read -r -a array; do
for word in "${array[@]}"; do
stuff;
done
done
回答by ashawley
To find what a control character is, run
要查找控制字符是什么,请运行
$ cat | od -b
^D
0000000 004 012
0000002
I typed ^V^Dafter issuing the command, and then RETand another ^D(unquoted) and the result is that EOF is octal 004.
我^V^D在发出命令后输入,然后输入RET另一个^D(未加引号),结果是 EOF 是八进制 004。
Combining that result with read(1)
:
将该结果与read(1)
:
$ read -d "$(echo -e 'while read line; do stuff "${line}"; done
4')" stdin
foo
bar quuz^Hx
^D
$ echo "$stdin"
foo
bar quux
$ for word in $stdin; do echo $word; done
foo
bar
quux
Yes, I typed ^Habove for backspace to see if read(1)
did the right thing. It does.
是的,我^H在上面输入了退格键,看看是否read(1)
做对了。确实如此。
回答by Daniel Nadasi
Two things...
两件事情...
The EOF character is represented by C-d (or C-v C-d if you want to type it), but to do what you're trying, it's better to do this:
EOF 字符由 Cd 表示(或者 Cv Cd,如果你想输入它),但是为了做你正在尝试的事情,最好这样做:
if test "$char" = '^V'; then...
回答by Colas Nahaboo
litb & Daniel are right, I will just answer your "Just for kick" question: Bash (as any command line unix program in general) only see characters as bytes. So you cannot match Alt-v, you will match whatever bytes are sent to you from the UI (pseudo-tty) that interpret these keypresses from the users. It can even be unix signals, not even bytes. It will depend on the terminal program used, the user settings and all kind of things so I would advise you not try to match them.
litb 和 Daniel 是对的,我只会回答你的“只是为了踢”问题:Bash(就像任何命令行 unix 程序一样)只将字符视为字节。因此,您无法匹配 Alt-v,您将匹配从解释这些用户按键的 UI(伪 tty)发送给您的任何字节。它甚至可以是 unix 信号,甚至不是字节。这将取决于所使用的终端程序、用户设置和所有类型的东西,因此我建议您不要尝试匹配它们。
But if you know that your terminal sends C-v as the byte number 22 (0x16), you can use things like:
但是,如果您知道您的终端将 Cv 作为字节数 22 (0x16) 发送,您可以使用以下内容:
##代码##by entering a real ^V char under your editor (C-q C-v under emacs, C-v C-v under an xterm , ...), not the two chars ^ and V
通过在编辑器下输入一个真正的 ^V 字符(emacs 下的 Cq Cv,xterm 下的 Cv Cv,...),而不是两个字符 ^ 和 V
回答by mdrc
My own terminal driver, when getc returns the EOT, fclose's stdout and reopens. That way, when reader's getc senses an empty write queue and returns the EOF (non char value) to signal it's closed, user sub-routines such as the `cat' can shift the argument and eventually quit. Thus renders the EOF a stream condition or file marker, no value in the range of ``char''.
我自己的终端驱动程序,当 getc 返回 EOT 时,fclose 的 stdout 并重新打开。这样,当读取器的 getc 检测到一个空的写入队列并返回 EOF(非字符值)以表示它已关闭时,诸如“cat”之类的用户子例程可以移动参数并最终退出。因此将 EOF 呈现为流条件或文件标记,在“char”范围内没有值。