read与键盘进行交互, 来取得变量的值
以下,googlebaidu参考:
http://bbs.chinaunix.net/thread-1581309-1-1.html
#!/bin/bash
printf "Please enter your username:"
read $USERNAME #获取键盘输入,赋值到变量USERNAME
echo "$USERNAME is XX"
====================================================================
http://www.360doc.com/content/12/0310/16/20669_193271365.shtml
使用read来进行变量分配
1 #!/bin/bash 2 # "Reading" 变量. 3 4 echo -n "Enter the value of variable 'var1': " 5 # -n 选项, 阻止换行. 6 7 read var1 8 # 注意: 在var1前面没有'$', 因为变量正在被设置. 9 10 echo "var1 = $var1" 11 12 13 echo 14 15 # 一个单独的'read'语句可以设置多个变量. 16 echo -n "Enter the values of variables 'var2' and 'var3' (separated by a space or tab): " 17 read var2 var3 18 echo "var2 = $var2 var3 = $var3" 19 # 如果你只输入了一个值, 那么其他的变量还是处于未设置状态(null). 20 21 exit 0 |
一个不带变量参数的read命令, 将会把来自键盘的输入存入到专用变量$REPLY中.
例子 11-4. 当使用一个不带变量参数的read命令时, 将会发生什么?
1 #!/bin/bash 2 # read-novar.sh 3 4 echo 5 6 # -------------------------- # 7 echo -n "Enter a value: " 8 read var 9 echo "\"var\" = "$var"" 10 # 到这里为止, 都与期望的一样. 11 # -------------------------- # 12 13 echo 14 15 # ------------------------------------------------------------------- # 16 echo -n "Enter another value: " 17 read # 没有变量分配给'read'命令, 所以... 18 #+ 输入将分配给默认变量, $REPLY. 19 var="$REPLY" 20 echo "\"var\" = "$var"" 21 # 这部分代码和上边的代码等价. 22 # ------------------------------------------------------------------- # 23 24 echo 25 26 exit 0 |
一般的, 当输入给read时, 输入一个\, 然后回车, 将会阻止产生一个新行. -r
选项将会让 \ 转义.
例子 11-5. read命令的多行输入
1 #!/bin/bash 2 3 echo 4 5 echo "Enter a string terminated by a \\, then press <ENTER>." 6 echo "Then, enter a second string, and again press <ENTER>." 7 read var1 # 当 read $var1 时, "\" 将会阻止产生新行. 8 # first line 9 # second line 10 11 echo "var1 = $var1" 12 # var1 = first line second line 13 14 # 对于每个以 "\" 结尾的行, 15 #+ 你都会看到一个下一行的提示符, 让你继续向var1输入内容. 16 17 echo; echo 18 19 echo "Enter another string terminated by a \\ , then press <ENTER>." 20 read -r var2 # -r 选项会让 "\" 转义. 21 # first line 22 23 echo "var2 = $var2" 24 # var2 = first line 25 26 # 第一个 <ENTER> 就会结束var2变量的录入. 27 28 echo 29 30 exit 0 |
read命令有些有趣的选项, 这些选项允许打印出一个提示符, 然后在不输入ENTER的情况下, 可以读入你所按下的字符的内容.
1 # 不敲回车, 读取一个按键字符. 2 3 read -s -n1 -p "Hit a key " keypress 4 echo; echo "Keypress was "\"$keypress\""." 5 6 # -s 选项意味着不打印输入. 7 # -n N 选项意味着只接受N个字符的输入. 8 # -p 选项意味着在读取输入之前打印出后边的提示符. 9 10 # 使用这些选项是有技巧的, 因为你需要用正确的顺序来使用它们. 11 |
read命令的-n
选项也可以检测方向键, 和一些控制按键.
例子 11-6. 检测方向键
1 #!/bin/bash 2 # arrow-detect.sh: 检测方向键, 和一些非打印字符的按键. 3 # 感谢, Sandro Magi, 告诉了我们怎么做到这点. 4 5 # -------------------------------------------- 6 # 按键所产生的字符编码. 7 arrowup='\[A' 8 arrowdown='\[B' 9 arrowrt='\[C' 10 arrowleft='\[D' 11 insert='\[2' 12 delete='\[3' 13 # -------------------------------------------- 14 15 SUCCESS=0 16 OTHER=65 17 18 echo -n "Press a key... " 19 # 如果不是上边列表所列出的按键, 可能还是需要按回车. (译者注: 因为一般按键是一个字符) 20 read -n3 key # 读取3个字符. 21 22 echo -n "$key" | grep "$arrowup" # 检查输入字符是否匹配. 23 if [ "$?" -eq $SUCCESS ] 24 then 25 echo "Up-arrow key pressed." 26 exit $SUCCESS 27 fi 28 29 echo -n "$key" | grep "$arrowdown" 30 if [ "$?" -eq $SUCCESS ] 31 then 32 echo "Down-arrow key pressed." 33 exit $SUCCESS 34 fi 35 36 echo -n "$key" | grep "$arrowrt" 37 if [ "$?" -eq $SUCCESS ] 38 then 39 echo "Right-arrow key pressed." 40 exit $SUCCESS 41 fi 42 43 echo -n "$key" | grep "$arrowleft" 44 if [ "$?" -eq $SUCCESS ] 45 then 46 echo "Left-arrow key pressed." 47 exit $SUCCESS 48 fi 49 50 echo -n "$key" | grep "$insert" 51 if [ "$?" -eq $SUCCESS ] 52 then 53 echo "\"Insert\" key pressed." 54 exit $SUCCESS 55 fi 56 57 echo -n "$key" | grep "$delete" 58 if [ "$?" -eq $SUCCESS ] 59 then 60 echo "\"Delete\" key pressed." 61 exit $SUCCESS 62 fi 63 64 65 echo " Some other key pressed." 66 67 exit $OTHER 68 69 # 练习: 70 # ----- 71 # 1) 使用'case'结构来代替'if'结构, 72 #+ 这样可以简化这个脚本. 73 # 2) 添加 "Home", "End", "PgUp", 和 "PgDn" 这些按键的检查. |
![]() |
对于read命令来说, |
read命令的-t
选项允许时间输入(参考例子 9-4).
read命令也可以从重定向的文件中"读取"变量的值. 如果文件中的内容超过一行, 那么只有第一行被分配到这个变量中. 如果read命令的参数个数超过一个, 那么每个变量都会从文件中取得一个分配的字符串作为变量的值, 这些字符串都是以定义的空白字符来进行分隔的. 小心使用!
例子 11-7. 通过文件重定向来使用read命令
1 #!/bin/bash 2 3 read var1 <data-file 4 echo "var1 = $var1" 5 # var1将会把"data-file"的第一行的全部内容都为它的值. 6 7 read var2 var3 <data-file 8 echo "var2 = $var2 var3 = $var3" 9 # 注意, 这里的"read"命令将会产生一种不直观的行为. 10 # 1) 重新从文件的开头开始读入变量. 11 # 2) 每个变量都设置成了以空白分割的字符串. 12 # 而不是之前的以整行的内容作为变量的值. 13 # 3) 而最后一个变量将会取得第一行剩余的全部部分(译者注: 不管是否以空白分割). 14 # 4) 如果需要赋值的变量个数比文件中第一行以空白分割的字符串个数还多的话, 15 # 那么这些变量将会被赋空值. 16 17 echo "------------------------------------------------" 18 19 # 如何用循环来解决上边所提到的问题: 20 while read line 21 do 22 echo "$line" 23 done <data-file 24 # 感谢, Heiner Steven 指出了这点. 25 26 echo "------------------------------------------------" 27 28 # 使用$IFS(内部域分隔变量)来将每行的输入单独的放到"read"中, 29 # 前提是如果你不想使用默认空白的话. 30 31 echo "List of all users:" 32 OIFS=$IFS; IFS=: # /etc/passwd 使用 ":" 作为域分隔符. 33 while read name passwd uid gid fullname ignore 34 do 35 echo "$name ($fullname)" 36 done </etc/passwd # I/O 重定向. 37 IFS=$OIFS # 恢复原始的$IFS. 38 # 这段代码也是Heiner Steven编写的. 39 40 41 42 # 在循环内部设置$IFS变量, 43 #+ 而不用把原始的$IFS 44 #+ 保存到临时变量中. 45 # 感谢, Dim Segebart, 指出了这点. 46 echo "------------------------------------------------" 47 echo "List of all users:" 48 49 while IFS=: read name passwd uid gid fullname ignore 50 do 51 echo "$name ($fullname)" 52 done </etc/passwd # I/O 重定向. 53 54 echo 55 echo "\$IFS still $IFS" 56 57 exit 0 |
![]() |
管道输出到read命令中, 使用管道echo输出来设置变量将会失败. 然而, 使用管道cat输出看起来能够正常运行.
但是, 就像Bj鰊 Eriksson所指出的: 例子 11-8. 管道输出到read中的问题
在许多Linux发行版上, gendiff脚本通常都在/usr/bin下, 将find的输出通过管道传到while read结构中.
|
############################################################################
http://blog.chinaunix.net/space.php?uid=20423564&do=blog&id=1949173
14.2 读取用户输入
14.2.1 变量
上一章我们谈到如何定义或取消变量,变量可被设置为当前shell的局部变量,或是环境变量。如果您的shell脚本不需要调用其他脚本,其中的变量通常设置为脚本内的局部变量(参见第13.10节“变量”)。
要获取变量的值,在美元符后跟变量名即可。shell会对双引号内的美元符后的变量执行变量扩展,单引号中的美元符则不会被执行变量扩展。
范例14-3
1 name="John Doe" or declare name="John Doe" # local variable
2 export NAME="John Doe" # global variable
3 echo "$name" "$NAME" # extract the value
14.2.2 read命令
read命令是一个内置命令,用于从终端或文件读 取输入(参见表14-1)。read命令读取一个输入行,直至遇到换行符。行尾的换行符在读入时将被转换成一个空字符。如果read命令后未跟变量名,读 入的行将被赋给内置变量REPLY。也可以用read命令来中断程序的运行,直至用户输入一个回车键。要知道如何有效地使用read命令从文件读取输入 行,请参见14.6节的“循环控制命令”。如果带-r选项,read命令将忽略反斜杠/换行符对,而把反斜杠作为行的一部分。read命令有4个控制选 项:-a,-e,-p,-r②。
表14-1 read命令
格 式 |
含 义 |
read answer |
从标准输入读取一行并赋值给变量answer |
read first last |
从标准输入读取一行,直至遇到第一个空白符或换行符。把用户键入的第一个词存到变量first中,把该行的剩余部分保存到变量last中 |
read |
标准输入读取一行并赋值给内置变量REPLY |
read –a arrayname |
读入一组词,依次赋值给数组arrayname③ |
(续表)
格 式 |
含 义 |
read -e |
在交互式shell命令行中启用编辑器。例如,如果编辑器是vi,则可以在输入行时使用vi命令③ |
read –p prompt |
打印提示符,等待输入,并将输入赋值给REPLY变量③ |
read –r line |
允许输入包含反斜杠③ |
范例14-4
(脚本)
#!/bin/bash
# Scriptname: nosy
echo -e "Are you happy? \c"
1 read answer
echo "$answer is the right response."
echo -e "What is your full name? \c"
2 read first middle last
echo "Hello $first"
echo –n "Where do you work? "
3 read
4 echo I guess $REPLY keeps you busy!
-------------------------------------------------------④
5 read -p "Enter your job title: "
6 echo "I thought you might be an $REPLY."
7 echo -n "Who are your best friends? "
8 read -a friends
9 echo "Say hi to ${friends[2]}."
-------------------------------------------------------
(输出)
$ nosy
Are you happy? Yes
1 Yes is the right response.
2 What is your full name? Jon Jake Jones
Hello Jon
3 Where do you work? the Chico Nut Factory
4 I guess the Chico Nut Factory keeps you busy!
5 Enter your job title: Accountant
6 I thought you might be an Accountant.
7,8 Who are your best friends? Melvin Tim Ernesto
9 Say hi to Ernesto.
说明
1. read命令接收一行用户输入,将其值赋给变量answer。
2. read命令从用户处接收输入,将输入的第一个词赋给变量first,将第二个词赋给变量middle,然后将直到行尾的所有剩余单词都赋给变量last。
3. 从标准输入读取一行,赋值给内置变量REPLY。
4. 显示变量REPLY的值。
5. 带-p选项的read命令,显示提示“Enter your job title:”,把输入行赋值给特定内置变量REPLY。
6. 在字符串中显示变量REPLY的值。
7. 请求用户输入。
8. 带-a选项的read命令将输入当作一组词组成的数组,数组名为friends,读入数组的元素是Melvin、Tim和Ernesto。
9. 显示friends数组的第3个元素。数组下标从0开始。
范例14-5
(脚本)
#!/bin/bash
# Scriptname: printer_check
# Script to clear a hung-up printer
1 if [ $LOGNAME != root ]
then
echo "Must have root privileges to run this program"
exit 1
fi
2 cat << EOF
Warning: All jobs in the printer queue will be removed.
Please turn off the printer now. Press return when you
are ready to continue. Otherwise press Control C.
EOF
3 read JUNK # Wait until the user turns off the printer
echo
4 /etc/rc.d/init.d/lpd stop # Stop the printer
5 echo -e "\nPlease turn the printer on now."
6 echo "Press Enter to continue"
7 read JUNK # Stall until the user turns the printer back on
echo # A blank line is printed
8 /etc/rc.d/init.d/lpd start # Start the printer
说明
1. 检查用户是否为root。如不是,则发送错误信息并退出。
2. 创建here文档。在屏幕上显示警告信息。
3. read命令等待用户输入。当用户按下回车键时,变量JUNK接收用户之前键入的内容。这个变量没什么实际用处。此处的read用来等待用户关闭打印机,然后回来按下回车键。
4. lpd命令终止打印机后台进程。
5. 现在重新打开打印机。
6. 如果已准备好,请求用户按下回车键。
7. 用户键入的任何内容都被读入变量JUNK,用户按下回车键之后,程序恢复运行。
8. lpd程序启动打印机后台进程。