Shell编程——输入与输出命令(read、echo、printf)

以下内容源于C语言中文网的学习与整理,如有侵权,请告知删除。

一、read命令

(1)read 是Shell内部命令,用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。

(2)read命令的用法:

read [-options] [variables]
  • options表示选项,variables表示用来存储数据的变量,可以有一个,也可以有多个。
  • optionsvariables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。

(3)Shell read 命令支持的选项如下表所示。

Shell read 命令支持的选项
选项说明
-a array把读取的数据赋值给数组 array,从下标 0 开始。
-d delimiter用字符串 delimiter 指定读取结束的位置,而不是一个换行符(读取到的数据不包括 delimiter)。
-e在获取用户输入的时候,对功能键进行编码转换,不会直接显式功能键对应的字符。
-n num读取 num 个字符,而不是整行字符。
-p prompt显示提示信息,提示内容为 prompt。
-r原样读取(Raw mode),不把反斜杠字符解释为转义字符。
-s静默模式(Silent mode),不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这是很有必要的。
-t seconds设置超时时间,单位为秒。如果用户没有在指定时间内输入完成,那么 read 将会返回一个非 0 的退出状态,表示读取失败。
-u fd使用文件描述符 fd 作为输入源,而不是标准输入,类似于重定向。

(4)例子1:使用 read 命令给多个变量赋值。注意,必须在一行内输入所有的值,不能换行,否则只能给第一个变量赋值,后续变量都会赋值失败。本例还使用了-p选项,该选项会用一段文本来提示用户输入。

#!/bin/bash

read -p "Enter some information > " name url age
echo "网站名字:$name"
echo "网址:$url"
echo "年龄:$age"

(5)例子2:只读取一个字符。-n 1表示只读取一个字符。运行脚本后,只要用户输入一个字符,立即读取结束,不用等待用户按下回车键。printf "\n"语句用来达到换行的效果,否则 echo 的输出结果会和用户输入的内容位于同一行,不容易区分。

#!/bin/bash

read -n 1 -p "Enter a char > " char
printf "\n"  #换行
echo $char

(6)例子3:在指定时间内输入密码。这段代码中,使用&&组合了多个命令,这些命令会依次执行,并且从整体上作为 if 语句的判断条件,只要其中一个命令执行失败(退出状态为非 0 值),整个判断条件就失败了,后续的命令也就没有必要执行了。

#!/bin/bash

if
    read -t 20 -sp "Enter password in 20 seconds(once) > " pass1 && printf "\n" &&  #第一次输入密码
    read -t 20 -sp "Enter password in 20 seconds(again)> " pass2 && printf "\n" &&  #第二次输入密码
    [ $pass1 == $pass2 ]  #判断两次输入的密码是否相等
then
    echo "Valid password"
else
    echo "Invalid password"
fi

如果两次输入密码相同,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Valid password

如果两次输入密码不同,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Invalid password

如果第一次输入超时,运行结果为:
Enter password in 20 seconds(once) > Invalid password

如果第二次输入超时,运行结果为:
Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)> Invalid password

二、echo命令

1、echo默认换行

echo 是Shell内部命令,用来向标准输出文件(一般指屏幕或者说终端)输出指定字符串,并在最后默认加上换行符。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bash

name="Shell教程"
url="http://c.biancheng.net/shell/"

echo "读者,你好!"  #直接输出字符串
echo $url  #输出变量
echo "${name}的网址是:${url}"  #双引号包围的字符串中可以解析变量
echo '${name}的网址是:${url}'  #单引号包围的字符串中不能解析变量
xjh@ubuntu:~/iot/tmp$ ./test.sh 
读者,你好!
http://c.biancheng.net/shell/
Shell教程的网址是:http://c.biancheng.net/shell/
${name}的网址是:${url}
xjh@ubuntu:~/iot/tmp$

2、关闭默认的换行

如果希望不换行,可以通过添加-n选项。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bash

name="Tom"
age=20
height=175
weight=62

echo -n "${name} is ${age} years old, "
echo -n "${height}cm in height "
echo "and ${weight}kg in weight."
echo "Thank you!"
xjh@ubuntu:~/iot/tmp$ ./test.sh 
Tom is 20 years old, 175cm in height and 62kg in weight.
Thank you!
xjh@ubuntu:~/iot/tmp$

3、输出转义字符

(1)默认情况下,echo 不会解析以反斜杠\开头的转义字符。比如,\n表示换行,echo 默认会将它作为普通字符对待。我们可以添加-e选项来让 echo 命令解析转义字符。

xjh@ubuntu:~/iot/tmp$ echo "hello \nworld"
hello \nworld
xjh@ubuntu:~/iot/tmp$ echo -e "hello \nworld"
hello 
world
xjh@ubuntu:~/iot/tmp$

(2)有了-e参数,我们也可以使用转义字符\c来强制 echo 命令不换行。\c这个转义字符表示不换行,然后-e选项表示让echo命令解析\c这个转义字符,即不换行?这似乎太饶了,不换行的话还是使用-n选项吧。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bash

name="Tom"
age=20
height=175
weight=62

echo -e "${name} is ${age} years old, \c"
echo -e "${height}cm in height \c"
echo "and ${weight}kg in weight."
echo "Thank you!"
xjh@ubuntu:~/iot/tmp$ ./test.sh 
Tom is 20 years old, 175cm in height and 62kg in weight.
Thank you!
xjh@ubuntu:~/iot/tmp$ 

三、printf命令

(1)printf 命令用于格式化输出,是echo命令的增强版,移植性要比 echo 好。

(2)printf 命令可以输出简单的字符串,但不像 echo 会自动换行,必须显式添加换行符(\n)。

xjh@ubuntu:~/iot/tmp$ printf "Hello, Shell\n"
Hello, Shell
xjh@ubuntu:~/iot/tmp$ printf "Hello, Shell"
Hello, Shellxjh@ubuntu:~/iot/tmp$ 

(3)printf 命令的使用格式如下,其中format-string 为格式控制字符串,arguments 为参数列表。

printf  format-string  [arguments...]

(4)printf 命令是C语言printf()库函数的一个有限的变形。

  • printf 命令不用加括号。
  • format-string 可以没有引号,但最好加上,单引号双引号均可。
  • 参数多于格式控制符(%)时,format-string 可以重用,可以将所有参数都转换。
  • arguments 使用空格分隔,不用逗号。

(5)实例演示

xjh@ubuntu:~/iot/tmp$ printf "%d %s\n" 1 "abc" #format-string使用双引号包围
1 abc
xjh@ubuntu:~/iot/tmp$ printf '%d %s\n' 1 "abc" #format-string使用单引号包围
1 abc
xjh@ubuntu:~/iot/tmp$

xjh@ubuntu:~/iot/tmp$ printf %s "abc"   #format-string没有引号包围时情况怪怪的
abcxjh@ubuntu:~/iot/tmp$ 
xjh@ubuntu:~/iot/tmp$ printf %s\n "abc" 
abcnxjh@ubuntu:~/iot/tmp$ 
xjh@ubuntu:~/iot/tmp$ 

#格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string被重用
xjh@ubuntu:~/iot/tmp$ printf %s abc def
abcdefxjh@ubuntu:~/iot/tmp$ 
xjh@ubuntu:~/iot/tmp$

xjh@ubuntu:~/iot/tmp$ printf "%s\n" abc def
abc
def
xjh@ubuntu:~/iot/tmp$ 

xjh@ubuntu:~/iot/tmp$ printf "%s %s %s\n" a b c d e f g h i j
a b c
d e f
g h i
j  
xjh@ubuntu:~/iot/tmp$

#如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
xjh@ubuntu:~/iot/tmp$ printf "%s and %d \n"
 and 0 
xjh@ubuntu:~/iot/tmp$

#如果以 %d 的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为 0
xjh@ubuntu:~/iot/tmp$ printf "The first program always prints'%s,%d\n'" Hello Shell
bash: printf: Shell: invalid number
The first program always prints'Hello,0
'xjh@ubuntu:~/iot/tmp$ 
xjh@ubuntu:~/iot/tmp$

(6)注意,根据POSIX标准,浮点格式%e、%E、%f、%g与%G是“不需要被支持”。这是因为awk支持浮点预算,且有它自己的printf语句。这样Shell程序中需要将浮点数值进行格式化的打印时,可使用小型的awk程序实现。然而,内建于bash、ksh93和zsh中的printf命令都支持浮点格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天糊土

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值