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