Linux笔记8——shell编程基础-2
补充——别名配置文件
- ~/.bashrc:对单个用户生效
- /etc/bashrc:对所有用户生效
source命令+配置文件脚本:把脚本命令运行在当前bash终端
只需要在这里写入所需要的命令别名,再通过source .bashrc加载即可
注:该配置文件后,一般需要重启服务(如httpd,ssh);若没有服务,则重启虚拟机(如SELinux);若配置文件是登录加载脚本,则用source命令
一、Bash常用快捷键
注:尽量不要对快捷键做出修改,毕竟服务器不是一个人在维护,你的习惯不是别人的习惯
二、输入输出重定向
- 输出:echo
- 输入:tee、wc(world count)
1.Bash的标准输入输出
设备 | 设备名 | 文件描述符 | 类型 |
键盘 | /etc/stdin | 0 | 标准输入 |
显示器 | /etc/stdout | 1 | 标准输出 |
显示器 | /etc/stdeer | 2 | 标准错误输出 |
2.输出重定向
作用:默认输出在当前终端,重定向到文件(>覆盖>>追加)(命令结果要正确)
#标准输出重定向,即把命令的正确输出输出到指定文件或设备中
格式1:命令 > 文件 #覆盖方式
格式2:命令 >> 文件 #追加方式
#标准错误输出重定向,即把命令的错误输出输出到指定文件或设备中
格式1:命令 2> 文件 #覆盖方式
格式2:命令 2>> 文件 #追加方式
#正确输出和错误输出同时重定向
#输出到同一个文件中
格式1:命令 > 文件 2>&1 或: 命令 &> 文件 #覆盖方式
格式2:命令 >> 文件 2>&1 或: 命令 &>> 文件 #追加方式
#输出到不同一个文件中
格式1:命令 > 文件1 2> 文件2 #覆盖方式
格式2:命令 >> 文件1 2>> 文件2 #追加方式
问题:输入命令,若命令正确,则结果放入dui.txt文件,命令错误,则结果放入cuo.txt文件
[root@localhost ~]# ls /root/ > dui.txt 2> cuo.txt
[root@localhost ~]# cat dui.txt
1.sh
anaconda-ks.cfg
cuo.txt
dui.txt
hello.sh
[root@localhost ~]# ls /root/sfhfa > dui.txt 2> cuo.txt
[root@localhost ~]# cat cuo.txt
ls: 无法访问 '/root/sfhfa': 没有那个文件或目录
EOF语法:非交互式的往文件中写入多行内容
#写多行,用EOF语法
<<EOF echo -e "\e[31m nihaoya~ \e[0m"
> echo "keyima"
> EOF
#EOF一般会配合cat实现多行文本输出:
#理解:cat的操作对象是文件,但是此处cat的操作对象不是文件,而是用户输入
cat <<efo
> echo -e "\e[31m nihaoya~ \e[0m"
> from test
> efo
#EOF配合cat也能将多行文本重定向到文件中(追加或覆盖都行):
cat << EOF > test.sh
> 123
> 456
> 789
> EOF
或:
cat > test.sh <<EOF
> abc
> def
> ghk
> EOF
#自定义结束符:
#EOF是END Of File的缩写,表示自定义终止符;即EOF不是固定的,可以随意设置别名
cat > t1.txt <<efo
> abc
> 123
> efo
或:
cat > t2.txt <<bbb
> abc
> 123
> bbb
3.输入重定向
作用:从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存在给定文件中
tee [选项] [文件]
- -a:内容追加到给定文件(默认是覆盖)
问题:将文件系统使用的信息追加到自建文件中(追加可以用来记录日志)
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 968M 0 968M 0% /dev/shm
tmpfs 388M 5.6M 382M 2% /run
/dev/nvme0n1p3 16G 2.4G 14G 15% /
/dev/nvme0n1p1 2.0G 278M 1.7G 15% /boot
tmpfs 194M 0 194M 0% /run/user/0
[root@localhost ~]# df -h | tee -a disk.log
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 968M 0 968M 0% /dev/shm
tmpfs 388M 5.6M 382M 2% /run
/dev/nvme0n1p3 16G 2.4G 14G 15% /
/dev/nvme0n1p1 2.0G 278M 1.7G 15% /boot
tmpfs 194M 0 194M 0% /run/user/0
[root@localhost ~]# cat disk.log
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 968M 0 968M 0% /dev/shm
tmpfs 388M 5.6M 382M 2% /run
/dev/nvme0n1p3 16G 2.4G 14G 15% /
/dev/nvme0n1p1 2.0G 278M 1.7G 15% /boot
tmpfs 194M 0 194M 0% /run/user/0
wc [选项] [文件]
- -l:统计行数
- -w:统计单词数(字符串,由空白、空格或换行符分隔的字符串)
- -c:统计字符数
[root@localhost ~]# wc anaconda-ks.cfg 42 99 989 anaconda-ks.cfg #行数 单词数 字符数 文件名
[root@localhost ~]# wc -l anaconda-ks.cfg
42 anaconda-ks.cfg
[root@localhost ~]# wc -w anaconda-ks.cfg
99 anaconda-ks.cfg
[root@localhost ~]# wc -c anaconda-ks.cfg
989 anaconda-ks.cfg
问题:单独输出行数、单词数、字符数
[root@localhost ~]# cat anaconda-ks.cfg | wc -l
42 #行数
[root@localhost ~]# cat anaconda-ks.cfg | wc -w
99 #单词数
[root@localhost ~]# cat anaconda-ks.cfg | wc -c
989 #字符数
注:wc不能直接输入查看字符串,只能查看文件(字符串可以用echo输出再wc查看);wc统计字符数量,也包括隐藏字符$(cat -A可以看到隐藏字符)
[root@localhost ~]# echo "hello world every people" | wc 1 4 25
[root@localhost ~]# echo "hello world every people" | wc -l
1
[root@localhost ~]# echo "hello world every people" | wc -w
4
[root@localhost ~]# echo "hello world every people" | wc -c
25
[root@localhost ~]# echo "hello world every people" | cat -A
hello world every people$
三、多命令执行顺序
命令1;命令2 | 多个命令顺序执行,命令间没有逻辑关系 |
命令1&&命令2 | 当命令1正确执行时才会执行命令2 |
命令1||命令2 | 当命令1执行不正确才会执行命令2 |
[root@localhost ~]# ls /root/ ; ls /root123
1.sh anaconda-ks.cfg a.txt cuo.txt disk.log dui.txt hello.sh ww.txt
ls: 无法访问 '/root123': 没有那个文件或目录
[root@localhost ~]# ls /root && ls /root123
1.sh anaconda-ks.cfg a.txt cuo.txt disk.log dui.txt hello.sh ww.txt
ls: 无法访问 '/root123': 没有那个文件或目录
[root@localhost ~]# ls /root123 && ls /root/
ls: 无法访问 '/root123': 没有那个文件或目录
[root@localhost ~]# ls /root123 ||ls /root/
ls: 无法访问 '/root123': 没有那个文件或目录
1.sh anaconda-ks.cfg a.txt cuo.txt disk.log dui.txt hello.sh ww.txt
四、通配符
[root@localhost bik.d]# ls
0123 0abc abc ABC abcd
[root@localhost bik.d]# ls abc*
abc abcd
[root@localhost bik.d]# ls abc?
abcd
[root@localhost bik.d]# ls ?abc
0abc
[root@localhost bik.d]# ls [A-Z]
ls: 无法访问 '[A-Z]': 没有那个文件或目录
[root@localhost bik.d]# ls [A-Z]*
ABC
[root@localhost bik.d]# ls [a-zA-Z]??
abc ABC
[root@localhost bik.d]# ls [^0-9]*
abc ABC abcd
五、grep命令
作用:过滤一个文件中的指定字符串,是行提取命令
选项:
- -A n:列出符合条件的行,并连续列出后续n行
- -B n:列出符合条件的行,并连续列出前面n行
- -c:统计符合条件的字符串行数
- -i:忽略大小写
- -n:输出行号
- -v:反向查找
- -o:只列出关键字
#列出passwd文件中带有ro字符的行
[root@localhost ~]# grep "ro" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
chrony:x:997:995:chrony system user:/var/lib/chrony:/sbin/nologin
#统计行数
[root@localhost ~]# grep -c "ro" /etc/passwd
3
#列出行号
[root@localhost ~]# grep -n "ro" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
19:chrony:x:997:995:chrony system user:/var/lib/chrony:/sbin/nologin
#只列出关键字
[root@localhost ~]# grep -o "ro" /etc/passwd
ro
ro
ro
ro
ro
ro
ro
#列出带有ro字符的行以及后续两行
[root@localhost ~]# grep -nA 2 "ro" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
--
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
--
19:chrony:x:997:995:chrony system user:/var/lib/chrony:/sbin/nologin
20-apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
问题:find和grep的区别
- find是在系统中找到符合条件的文件名,默认是完全匹配,需要使用通配符进行模糊匹配
- grep是在文件中查找符合条件的字符串,是包含(模糊)匹配,如果要精确查询,需要使用正则表达式。例:
注:在正则表达式中,*表示前一个字符出现的次数(0个或任意多个),如ro*,0个则表示关键字只有r,任意多个则可以是ro,也可以是roo,rooo等
六、Bash中的其他特殊符号
#$调用变量的值
[root@localhost ~]# name="chengtiankun"
[root@localhost ~]# echo $name
chengtiankun
[root@localhost ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
#单引号所有符号都是普通字符
[root@localhost ~]# echo "$name"
chengtiankun
[root@localhost ~]# echo '$name'
$name
#反引号执行系统命令,然后取命令的运行结果,可以赋值给变量
[root@localhost ~]# echo `ls`
1.sh anaconda-ks.cfg a.txt bik.d cuo.txt disk.log dui.txt hello.sh ww.txt
[root@localhost ~]# name=`ls`
[root@localhost ~]# echo $name
1.sh anaconda-ks.cfg a.txt bik.d cuo.txt disk.log dui.txt hello.sh ww.txt
#$()引用系统命令
[root@localhost ~]# echo $(ls)
1.sh anaconda-ks.cfg a.txt bik.d cuo.txt disk.log dui.txt hello.sh ww.txt
#[]测试变量,同test命令
[root@localhost ~]# test a == a && echo 等 || echo 不等
等
[root@localhost ~]# test a == b && echo 等 || echo 不等
不等
[root@localhost ~]# [ a == a ] && echo 等 || echo 不等
等
[root@localhost ~]# [ a == b ] && echo 等 || echo 不等
不等
补充——两个整数之间进行比较
- -eq:相等
- -ne:不相等
- -gt:大于
- -lt:小于
- ge:大于等于
- le:小于等于
[root@localhost ~]# [ 1 -eq 2 ] && echo 等 || echo 不等
不等
[root@localhost ~]# [ 1 -eq 1 ] && echo 等 || echo 不等
等
[root@localhost ~]# [ 1 -gt 2 ] && echo yes || echo no
no
[root@localhost ~]# [ 1 -lt 2 ] && echo yes || echo no
yes