前言:在编写sh脚本的时候,发现使用read命令和预期的效果不一样,,因为shell用的是zsh,查了一下发现bash和zsh中read命令的用法有些区别,这里记录一下。
读取字符
从标准输入中读取一个或多个字符
bash: read -n num input
zsh: read -k num input
例子:
root@hcss-ecs-b5f1 ~ ❯ read -k 1 myinput 02:04:11 PM
a
root@hcss-ecs-b5f1 ~ ❯ echo $myinput 02:16:01 PM
a
提示符
在读取输入之前显示的提示符
bash: read -p "prompt" message
zsh: read "message?prompt"
,如果 read 命令的第一个参数包含一个问号(?),那么问号后面的内容将被解释为提示符,并且当shell处于交互模式时,这个提示符会显示在标准错误输出(通常是终端)上。
例子:
root@hcss-ecs-b5f1 ~ ❯ read "message?what?" 02:03:54 PM
what?ssss
root@hcss-ecs-b5f1 ~ 5s ❯ echo $message 02:04:06 PM
ssss
Zsh中的read命令及其参数说明
这部分是我从该文档[原文地址]中复制后机翻过来的。
通过man zshbuiltins
,也可以查看zsh文档。
read [ -rszpqAclneE ] [ -t [ num ] ] [ -k [ num ] ] [ -d delim ][ -u n ] [ [name][?prompt] ] [ name ... ]
读取一行输入并根据$IFS变量中的字符作为分隔符将其分割成字段,下面有例外情况说明。第一个字段被赋值给第一个名称变量,第二个字段给第二个名称变量,以此类推,多余的字段则全部赋值给最后一个名称变量。如果省略了名称变量,则对于标量使用REPLY,而对于数组则使用reply。
-r
:原始模式:行尾的‘\’不表示续行,行内的反斜杠也不转义后续字符且不会被移除。-s
:从终端读取时不回显输入的字符。-q
:仅从终端读取一个字符,若该字符为'y'或'Y'则将变量设为'y',否则设为'n'。带有此标志时,只有当字符为'y'或'Y'时返回状态才为0。此选项可与超时(见-t)一起使用;如果读取超时或遇到文件结尾(End of File),返回状态2。除非指定了-u
或-p
,否则输入来自终端。此选项也可在zle小部件中使用。-k [ num ]
:仅读取一个(或num个)字符。所有字符都赋值给第一个变量,不分割单词。当-q
存在时,此标志被忽略。除非使用了-u
或-p
选项,否则从终端读取输入。此选项也可以在zle小部件中使用。注意,尽管助记符是'key',此选项确实读取完整的字符,如果设置了MULTIBYTE选项,字符可能由多个字节组成。-z
:从编辑器缓冲区堆栈中读取一项并赋值给第一个变量,不分割单词。文本通过print -z
或行编辑器中的push-line(见Zsh行编辑器)推送到堆栈。当-k或-q标志存在时忽略此选项。-e / -E
:读取的输入会打印到标准输出。如果使用-e
标志,则不将任何输入赋值给参数。-A
:将第一个变量视为数组并将所有单词赋值给它。-c / -l
:仅在用于补全的函数内允许(用compctl
的-K
标志指定)。如果有-c
标志,则读取当前命令的单词。如果有-l
标志,则整个行作为标量赋值。如果两个标志都存在,则使用-l
,忽略-c
。-n
:与-c
一起使用时,读取光标所在的单词编号。与-l
一起使用时,读取光标所在的字符索引。注意命令名为单词1而非0,并且当光标在行末时,其字符索引为行长度加一。-u n
:从文件描述符 n 中读取输入。-p
:从协进程中读取 Input。-d delim
:输入以delim的第一个字符结束而不是换行符。-t [ num ]
:在尝试读取之前测试是否有输入可用。如果num存在,它必须以数字开头,并将被评估为秒数,可以是浮点数;在这种情况下,如果在此时间内没有输入可用,则读取超时。如果num不存在,则默认为零,因此如果没有输入可用,read会立即返回。如果没有输入可用,则返回状态1且不设置任何变量。- 当使用
-z
从编辑器缓冲区读取时,或在补全中使用-c
或-l
调用时,或使用-q
时(它在读取前清除输入队列),或在zle中(应使用其他机制来测试输入),此选项不可用。 - 请注意,read不会尝试更改输入处理模式。默认模式是规范输入,即一次读取整行,因此通常
read -t
在整行输入之前不会读取任何内容。然而,当使用-k从终端读取时,输入是一个键一个键地处理的;在这种情况下,仅测试第一个字符的可用性,因此例如read -t -k 2
仍然可能在第二个字符上阻塞。如果不希望这样,可以使用两个read -t -k
实例。 - 如果第一个参数包含'?',则该词的其余部分在交互式shell中作为标准错误上的提示符使用。
- 当遇到文件结束符时,或当-c或-l存在且命令不是从compctl函数调用时,或如-q所述时,read的返回值(退出状态)为1。否则返回值为0。
- 某些
-k
,-p
,-q
,-u
和-z
标志组合的行为未定义。目前-q
取消所有其他选项,-p
取消-u
,-k
取消-z
,而-z
取消-p
和-u
。 -c
或-l
标志取消任何和所有的-kpquz
。
以下为原文内容:
read [ -rszpqAclneE ] [ -t [ num ] ] [ -k [ num ] ] [ -d delim ][ -u n ] [ [name][?prompt] ] [ name ... ]
Read one line and break it into fields using the characters in $IFS as separators, except as noted below. The first field is assigned to the first name, the second field to the second name, etc., with leftover fields assigned to the last name. If name is omitted then REPLY is used for scalars and reply for arrays.-r
Raw mode: a ‘\’ at the end of a line does not signify line continuation and backslashes in the line don’t quote the following character and are not removed.-s
Don’t echo back characters if reading from the terminal.-q
Read only one character from the terminal and set name to ‘y’ if this character was ‘y’ or ‘Y’ and to ‘n’ otherwise. With this flag set the return status is zero only if the character was ‘y’ or ‘Y’. This option may be used with a timeout (see -t); if the read times out, or encounters end of file, status 2 is returned. Input is read from the terminal unless one of -u or -p is present. This option may also be used within zle widgets.-k [ num ]
Read only one (or num) characters. All are assigned to the first name, without word splitting. This flag is ignored when -q is present. Input is read from the terminal unless one of -u or -p is present. This option may also be used within zle widgets.Note that despite the mnemonic ‘key’ this option does read full characters, which may consist of multiple bytes if the option MULTIBYTE is set.-z
Read one entry from the editor buffer stack and assign it to the first name, without word splitting. Text is pushed onto the stack with ‘print -z’ or with push-line from the line editor (see Zsh Line Editor). This flag is ignored when the -k or -q flags are present.
-e
-E
The input read is printed (echoed) to the standard output. If the -e flag is used, no input is assigned to the parameters.-A
The first name is taken as the name of an array and all words are assigned to it.-c
-l
These flags are allowed only if called inside a function used for completion (specified with the -K flag to compctl). If the -c flag is given, the words of the current command are read. If the -l flag is given, the whole line is assigned as a scalar. If both flags are present, -l is used and -c is ignored.-n
Together with -c, the number of the word the cursor is on is read. With -l, the index of the character the cursor is on is read. Note that the command name is word number 1, not word 0, and that when the cursor is at the end of the line, its character index is the length of the line plus one.-u n
Input is read from file descriptor n.-p
Input is read from the coprocess.-d delim
Input is terminated by the first character of delim instead of by newline.-t [ num ]
Test if input is available before attempting to read. If num is present, it must begin with a digit and will be evaluated to give a number of seconds, which may be a floating point number; in this case the read times out if input is not available within this time. If num is not present, it is taken to be zero, so that read returns immediately if no input is available. If no input is available, return status 1 and do not set any variables.This option is not available when reading from the editor buffer with -z, when called from within completion with -c or -l, with -q which clears the input queue before reading, or within zle where other mechanisms should be used to test for input.Note that read does not attempt to alter the input processing mode. The default mode is canonical input, in which an entire line is read at a time, so usually ‘read -t’ will not read anything until an entire line has been typed. However, when reading from the terminal with -k input is processed one key at a time; in this case, only availability of the first character is tested, so that e.g. ‘read -t -k 2’ can still block on the second character. Use two instances of ‘read -t -k’ if this is not what is wanted.If the first argument contains a ‘?’, the remainder of this word is used as a prompt on standard error when the shell is interactive.The value (exit status) of read is 1 when an end-of-file is encountered, or when -c or -l is present and the command is not called from a compctl function, or as described for -q. Otherwise the value is 0.The behavior of some combinations of the -k, -p, -q, -u and -z flags is undefined. Presently -q cancels all the others, -p cancels -u, -k cancels -z, and otherwise -z cancels both -p and -u.The -c or -l flags cancel any and all of -kpquz.
参考资料
read 在 zsh 和 bash 下的不同
The Z Shell Manual - Shell Builtin Commands