IO操作¶
命令汇总
0x00 read¶
参考文档:shell脚本之read命令
read命令是用来获取用户输入内容,即标准输入设备(键盘)输入内容,它是shell内建命令,使用help read命令可以查看其语法格式和使用说明,它的语法格式如下
read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [var_name ...]
其执行逻辑如下
read命令从标准输入设备中读取输入单行,默认单行的结束符号为回车换行符- 此处需要注意的是:不带任何选项的read命令,只有按下回车键才能结束read命令的读取
然后将读取的单行根据
IFS环境变量分裂成多个字段,并将分割后的字段分别赋值给read命令后面指定的变量列表var_name,其赋值逻辑如下- 第一个字段分配给第一个变量
var_name1,第二个字段分配给第二个变量var_name2,依次到结束 - 如果指定的变量名少于字段数量,则多出的字段数量也同样分配给最后一个
var_name - 如果指定的变量命令多于字段数量,则多出的变量赋值为空
- 如果没有指定任何
var_name,则分割后的所有字段都存储在特定变量REPLY中
- 第一个字段分配给第一个变量
read命令的常用选项有
-a:将分隔后的字段依次存储到-a指定的数组中,存储的起始位置从数组的index=0开始-d:指定读取行的结束符号,默认结束符号为换行符-n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取-N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束,其中换行符或回车算一个字符-p:输出提示符或提示语,默认不支持\n换行,要换行需要特殊处理-r:禁止反斜线的转义功能,这意味着\会变成文本的一部分-s:静默模式,输入的内容不会回显在屏幕上,常用来获取密码输入-t:给出超时时间,在达到超时时间时,read退出并返回错误,也就是说不会读取任何内容,即使已经输入了一部分
-a选项将读取的内容分配给数组变量,从索引号0开始分配
-d选项指定读取行的结束符号,而不再使用换行符
-n和-N选项限制输入字符
-p选项输出提示字符串
-p选项默认不带换行功能,且也不支持\n换行,但通过$'string'的方式特殊处理,就可以实现换行的功能;关于$'String'和$"String"的作用,详见shell中加引号有什么用
-s选项用来获取密码输入
-t选项给出输入时间限制,没完成的输入将被丢弃,所有变量将赋值为空(如果在执行read前,变量已被赋值,则此变量在read超时后将被覆盖为空)
read也可以用来在shell脚本中读取文件内容
# 每读取文件一行内容,就会进入一次while循环,直到读完文件尾部退出循环
# 读取文件方法一
while read line; do
echo $line
done < /etc/passwd
# 读取文件方法二
exec </etc/passwd;while read line; do
echo $line
done
0x01 echo¶
echo命令类似于c中printf,用于标准输出,它是shell内建命令,使用help read命令可以查看其语法格式和使用说明,它的语法格式如下
echo [-neE] [arg ...]
它的执行逻辑是:将给定arg内容按照-neE选项指定的不同方式输出
echo命令常用的选项有
-n:取消分行输出-e:支持字符串内转义字符的显示输出
关于echo命令的使用,主要关注一些几点
echo中的引号和感叹号:在bash环境中,感叹号只能通过单引号包围来输出,不能通过双引号来包围输出,原因有
- 在bash环境中,感叹号表示引用历史命令,除非设置
set +H关闭历史命令的引用 '':单引号表示强引用,该操作符的优先级大于!,即不会进行历史命令的引用,直接引用显示全部字符"":双引号表示弱引用,该操作符的优先级小于!,即先进行历史命令的引用,然后再引用显示全部字符
- 在bash环境中,感叹号表示引用历史命令,除非设置
- echo中的转义:通过
-e选项识别转义和特殊意义的符号,如换行符\n、制表符\t、转义符\等
echo "hello world" # 打印字符串
# -e选项支持字符串内转义字符的显示输出
echo -e "hello\bworld" # 删除前面的字符,输出hellworld
echo -e "hello\tworld" # 制表符,输出hello world
echo -e "hello\vworld" # 垂直制表符
echo -e "hello\nworld" # 换行符
- echo中的分行处理:默认情况下
echo会在每行行尾加上换行符号,使用-n选项可以取消分行输出
echo中的颜色输出:echo可以控制字体颜色和背景颜色输出,因为需要使用特殊符号,所以需要配合
-e选项来识别特殊符号常见的字体颜色:
重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,紫色=35,天蓝色=36,白色=37常见的背景颜色:
重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,紫色=45,天蓝色=46,白色=47字体控制选项:
1表示高亮,4表示下划线,5表示闪烁着色显示字符串格式为:
"\033[@;@mSTRING\033[0;0m"从左往右各字段的含义依次是\033表示定义一个转义序列,也可以使用\e[表示开始定义颜色@;@表示颜色定义,第一个@表示字背景颜色,颜色范围40–47;;用来分隔字背景颜色和文字颜色;第二个@表示文字颜色,颜色范围30–37。如果没有相关定义则表示默认颜色m表示颜色定义完毕STRING表示要输出的字符串\033表示定义一个转义序列,也可以使用\e[表示再次开启颜色定义0;0m表示将前面定义的背景颜色和文字颜色重置为默认颜色;注意定义了颜色之后就需要使用此项来重置关闭颜色,否则会继续影响bash环境的颜色,前面定义了几个@,该处就应该使用几个0来重置对应的颜色
echo -e "\033[32mhello\033[0m" # 着色显示,默认背景颜色,字颜色为32绿色
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m"
echo -e "\033[42;37m 绿底白字 \033[0m"
echo -e "\033[43;37m 黄底白字 \033[0m"
echo -e "\033[44;37m 蓝底白字 \033[0m"
echo -e "\033[45;37m 紫底白字 \033[0m"
echo -e "\033[46;37m 天蓝底白字 \033[0m"
echo -e "\033[47;30m 白底黑字 \033[0m"
echo -e "\033[41;37;0m 关闭所有属性 \033[0m"
echo -e "\033[41;37;1m 设置高亮度 \033[0m"
echo -e "\033[41;37;4m 下划线 \033[0m"
echo -e "\033[41;37;5m 闪烁 \033[0m"
echo -e "\033[41;37;7m 反显 \033[0m"
echo -e "\033[41;37;8m 消隐 \033[0m"
0x02 printf¶
使用printf命令可以输出比echo更规则更格式化的结果,它引用于C语言的printf函数,但是有些许区别;它也是shell内建命令,使用help printf命令可以查看其语法格式和使用说明,它的语法格式如下
printf [-v var] format [arguments]
其执行逻辑是:按照format定义的输出格式将arguments输出到指定位置;默认是输出到标准输出,如果使用了-v选项表示将arguments按照指定格式赋值给该选项指定的变量var
使用printf最需要注意以下两点
printf默认不在结尾加换行符,它不像echo一样,所以要手动加\n换号符printf只是格式化输出,不会改变任何结果,所以在格式化浮点数的输出时,浮点数结果是不变的,仅仅只是改变了显示的结果
使用printf可以实现
- 指定字符串的宽度
- 实现左对齐(使用
-) - 实现右对齐(默认值)
- 格式化小数输出
#!/bin/bash
# 三个%分别对应后面的三个参数
# 减号"-"表示左对齐,默认表示右对齐
# 减号"-"后面的数字n表示占用n个字符
# 点号"."后面的数字m表示取小数点后m位
# s表示对应一个字符串变量
# f表示对应一个浮点数变量
# d表示对应一个整数变量
# \t表示制表符
# \n表示换行符
printf "%-s\t %-s\t %s\n" No Name Mark
printf "%-s\t %-s\t %4.2f\n" 1 Sarath 80.34
printf "%-s\t %-s\t %4.2f\n" 2 James 90.998
printf "%-s\t %-s\t %4.2f\n" 3 Jeff 77.564
# 执行结果如下
# No Name Mark
# 1 Sarath 80.34
# 2 James 91.00
# 3 Jeff 77.56