Shell 学习
1. $?
返回0,代表上一行代码执行成功。
访问非0,代表上一行代码执行失败。
#ping.sh
ping -c1 www.baidu.com &>/dev/null && echo "www.baidu.com is up" ||echo "www.baidu.com is down!"
&& 如果 ? = 0 执 行 ∣ ∣ 如 果 ?=0 执行 || 如果 ?=0执行∣∣如果?!=0 执行
2. Shell重定向
0 表示标准输入
1 表示标准输出
2 表示标准错误输出
> 默认为标准输出重定向,与 1>相同
2>&1 把标准错误输出 重定向到标准输出
&>file 把标准输出 和 标准错误输出 都重定向到文件file中
请注意: >和& 直接没有间隔
例子:
1.全部输出
root@prox-31:/tmp# grep deb-systemd-helper-enabled *
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directory
2.只输出 标准输出
aa/1.log 里面只有标准输出, 错误信息就不显示了
root@prox-31:/tmp# grep deb-systemd-helper-enabled * 1> aa/1.log
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directory
root@prox-31:/tmp# cat aa/1.log
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
3.只输出标准错误输出
aa/2.log只有错误输出
root@prox-31:/tmp# grep deb-systemd-helper-enabled * 2> aa/2.log
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
root@prox-31:/tmp# cat aa/2.log
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directo
- 标准输出 重定向到 标准错误输出
aa/all.log 为空,证明标准输出被重定向到了 标准错误输出,所以文件就为空
root@prox-31:/tmp# grep deb-systemd-helper-enabled * > aa/all.log 1>&2
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directory
root@prox-31:/tmp# cat aa/all.log
root@prox-31:/tmp#
- 标准错误输出重定向导 标准输出
标准错误输出和标准输出都 重定向到文件中
root@prox-31:/tmp# grep deb-systemd-helper-enabled * > aa/all2.log 2>&1
root@prox-31:/tmp# cat aa/all2.log
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directory
- &>file 类似于5 把标准输出和 标准错误输出 都重定位到文件file中
root@prox-31:/tmp# grep deb-systemd-helper-enabled * &> aa/all3.log
root@prox-31:/tmp# cat aa/all3.log
1.log:./lib/systemd/deb-systemd-helper-enabled/rpcbind.socket.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/iscsid.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/corosync.service.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/nfs-client.target.dsh-also
1.log:./lib/systemd/deb-systemd-helper-enabled/pve-lxc-syscalld.service.dsh-also
grep: aa: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-corosync.service-L266Hb: Is a directory
grep: systemd-private-7044c227482f4cbbba56b0c3026d8182-systemd-timesyncd.service-zdcC89: Is a directory
3. #! 解释器标识符
shell脚本 tesh.sh
#! /usr/bin/bash
ping -c1 www.baidu.com
./test.sh 用/usr/bin/bash 执行
#! /usr/bin/python
ping -c1 www.baidu.com
./test.sh 用/usr/bin/python 执行,执行报错
root@prox-31:/tmp# ./1.sh
File "./1.sh", line 2
ping -c1 www.baidu.com
^
SyntaxError: invalid syntax
3. shell调用python代码
#!/usr/bin/bash
ping -c1 www.baidu.com
/usr/bin/python <<-EOF
print "hello world"
EOF
echo "Hello bash"
4.python里面调用shell代码
#!/usr/bin/python
import os
print "hello world!"
val = os.system('ls -al')
print val
5.当前shell 与子shell的区别
#!/usr/bin/bash
cd /home
ls -rlt
执行子shell命令,目录没有变
bash 1.sh
[root@master tmp]# bash 1.sh
total 8
drwx------. 7 nagios nagios 4096 Mar 28 2019 nagios
drwx------ 3 1002 1002 127 Apr 9 2019 user1
drwx------ 4 zabbix zabbix 139 Dec 27 2019 zabbix
-rw-r----- 1 root root 716 Mar 24 00:02 index.html
drwxr-x--- 6 root root 89 Mar 24 19:03 NetworkPolicy
drwxr-x--- 4 root root 38 Apr 23 18:33 traefik
drwxr-x--- 2 root root 82 Apr 24 13:40 Service
You have new mail in /var/spool/mail/root
[root@master tmp]# ./1.sh
total 8
drwx------. 7 nagios nagios 4096 Mar 28 2019 nagios
drwx------ 3 1002 1002 127 Apr 9 2019 user1
drwx------ 4 zabbix zabbix 139 Dec 27 2019 zabbix
-rw-r----- 1 root root 716 Mar 24 00:02 index.html
drwxr-x--- 6 root root 89 Mar 24 19:03 NetworkPolicy
drwxr-x--- 4 root root 38 Apr 23 18:33 traefik
drwxr-x--- 2 root root 82 Apr 24 13:40 Service
当前shell,目录变了
. 1.sh
source 1.sh
[root@master tmp]# source 1.sh
total 8
drwx------. 7 nagios nagios 4096 Mar 28 2019 nagios
drwx------ 3 1002 1002 127 Apr 9 2019 user1
drwx------ 4 zabbix zabbix 139 Dec 27 2019 zabbix
-rw-r----- 1 root root 716 Mar 24 00:02 index.html
drwxr-x--- 6 root root 89 Mar 24 19:03 NetworkPolicy
drwxr-x--- 4 root root 38 Apr 23 18:33 traefik
drwxr-x--- 2 root root 82 Apr 24 13:40 Service
[root@master tmp]# . 1.sh
total 8
drwx------. 7 nagios nagios 4096 Mar 28 2019 nagios
drwx------ 3 1002 1002 127 Apr 9 2019 user1
drwx------ 4 zabbix zabbix 139 Dec 27 2019 zabbix
-rw-r----- 1 root root 716 Mar 24 00:02 index.html
drwxr-x--- 6 root root 89 Mar 24 19:03 NetworkPolicy
drwxr-x--- 4 root root 38 Apr 23 18:33 traefik
drwxr-x--- 2 root root 82 Apr 24 13:40 Service
6. login shell 和nologin shell的区别
login shell /bin/bash su - xiaojun /etc/profile /etc/bashrc ~/.bash_profile ~/.bashrc
nologin shell /sbin/nologin su xiaojun /etc/bashrc ~/.bashrc
7.执行历史命令
!number
!string #匹配字符的命令
!$ #上个命令最后一个参数
!! #上一条命令
ctrl + R #匹配历史命令
8.别名
alias
9.快捷键
ctrl +R #history命令匹配查找
ctrl +D #退出bash
ctrl +A #到命令头
ctrl +E #到命令尾
ctrl +U #删除光标到命令行头
ctrl +K #删除光标到命令行尾
ctrl +L #清除终端屏幕,相当于clear命令
Ctrl + s:在终端下是有特殊用途的,那就是暂停该终端,
Ctrl + q 退出这种状态,让终端继续运行
注:即便终端在锁定状态下,你输入的命令虽然无法在屏幕上显示出来,但是敲下回车的时候还是会执行的,锁定的时候可别在键盘上乱按乱点
10 Screen
[root@master ~]# screen -list
There is a screen on:
28489.pts-0.master (Detached)
1 Socket in /var/run/screen/S-root.
[root@master ~]# screen -r 28489
[root@master ~]# sleep 7000
11.作业前后台切换
[root@master ~]# sleep 7000
^Z
[1]+ Stopped sleep 7000
[root@master ~]# bg
[1]+ sleep 7000 &
[root@master ~]# jobs
[1]+ Running sleep 7000 &
[root@master ~]# fg
sleep 7000
^Z
[1]+ Stopped sleep 7000
[root@master ~]# bg
[1]+ sleep 7000 &
[root@master ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.10.129 xen10-129.ebaotech.com xen10-129
172.25.10.129 master
172.25.10.131 node1
172.25.10.132 node2
172.25.10.212 node3
"/etc/hosts" 7L, 297C
[2]+ Stopped vi /etc/hosts ##Ctrl + Z退出
[root@master ~]# fg
vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.10.129 xen10-129.ebaotech.com xen10-129
172.25.10.129 master
172.25.10.131 node1
172.25.10.132 node2
172.25.10.212 node3
12.管道 tee
date > date.txt # 不会显示到前台
date | tee date.txt # 既能输入到文件又能显示到前台
13 shell通配符(元字符)
- #匹配任意字符。 find / -name “-eth0”
? #匹配单个字符
[] #匹配括号中任意一个字符[abc][a-z][0-9][a-zA-Z0-9] ^a-z ,ll[io]ve ;ll /dev/sd[a-z]*
() # 在子shell中执行(cd /boot;ls)(umask 077;touch file1000)
{} #表示集合 mkdir -pv {333/{aaa,bbb},444}
cp -rv /etc/sysconfig/network-scripts/{ifcfg-eth0,ifcfg-eth0.old}
cp -rv /etc/sysconfig/network-scripts/ifcfg-eth0{,.old}
14 \转义字符
echo * 星号
touch yang\ sheng 空格
echo -e "a\nb
a
b
echo -e "a\tb"
15 颜色输出
echo -e "\e[1;31mThis is a red"
echo -e "\e[1;32mThis is a blue"
echo -e "\e[1;32mThis is a blue\e[0m Test" [0m 结束颜色
printf 格式化输出
16 变量
ping02.sh
#!/usr/bin/bash
ip=10.18.42.2
ping -c1 $ip &>/dev/null && echo "$ip is up" || echo "$ip is down"
#!/usr/bin/bash
ip=10.18.42.1
if ping -c1 $ip &>/dev/null ;then
echo "$ip is up."
else
echo "$ip is down."
fi
#!/usr/bin/bash
ip=10.18.42.1
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ] ;then
echo "$ip is up."
else
echo "$ip is down."
fi
type -a [ #查看[的意思
#!/usr/bin/bash
read -p "Please input a ip:" ip
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ] ;then
echo "$ip is up."
else
echo "$ip is down."
fi
#!/usr/bin/bash
ip=$1
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ] ;then
echo "$ip is up."
else
echo "$ip is down."
fi
17.预定义变量
$0 脚本名
$* 所有的参数
$@ 所有的参数
$# 参数的个数
$$ 当前进程的pid
$! 上一个后台进程的pid
$? 上一个命令的返回值 0,表示成功,非0表示失败
#!/usr/bin/bash
#如果用户没有加参数
if [ $# -eq 0 ];then
echo "usage: $0 file"
exit
fi
if [ ! -f $1 ];then
echo "error file!"
exit
fi
for ip in `cat $1`
do
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip is up"
else
echo "$ip is down"
fi
done
18 变量赋值
- 显示赋值
变量名=变量值ip1=172.18.6.12 school="Beijing 1000" today1=`date +%F` today2=$(date +%F)
- read 从键盘读入变量值
read -p "Please input ip:" ip #提示输入
read -t 5 -p "提示信息:" 变量名 #等待5s
read -n 2 name #只取前面两个值
read ip1 ip2 ip3 ip4 #取4个值
#!/usr/bin/bash
read -p "输入姓名:" name
read -p "输入性别:" gender
read -p "输入年龄:" age
#!/usr/bin/bash
read -p "输入姓名,性别,年龄:" name gender age
单引号 弱引用,无法将变量变成值
双引号 强引用,可以将变量变成值
disk_free=`df -Ph|grep '/$'|awk '{print $4}'`
disk_free=echo $(df -Ph|grep '/$'|awk '{print $4}')
root@prox-17:~# url=www.sina.com.cn
root@prox-17:~# echo ${url#*.}
sina.com.cn
root@prox-17:~# echo ${url##*.}
cn
root@prox-17:~# echo ${url#www.si}
na.com.cn
替换
root@prox-17:~# echo ${url//n/N}
www.siNa.com.cN
root@prox-17:~# unset var1
root@prox-17:~# echo ${var1:-aaaa}
aaaa
root@prox-17:~# var2=
root@prox-17:~# echo ${var2:-aaaa}
aaaa
root@prox-17:~# var3=111
root@prox-17:~# echo ${var3:-aaaa} #有值的无法替换
111
19 调试脚本
sh -n 1.sh 仅调试syntax error
sh -vx 1.是 以调试的方式执行,查询整个执行过程
20 shell 条件测试
格式1: test条件表达式
格式2: [ 条件表达式 ]
格式3: [[ 条件表达式 ]]
test -d /home
echo $?
#!/usr/bin/bash
back_dir=/var/mysql_back
if ! test -d $back_dir;then
mkdir -p $back_dir
fi
[ -d /home ]
echo $?
[ -d /home ]
[ -f file ] 文件是否存在
[ -r file ] 当前用户对文件是否有读权限
[ -x file ] 当前用户对文件是否有执行权限
[ -w file ] 当前用户对文件是否有写权限
[ -L file ] 文件是否是链接
[ ! -d /ccc ] && mkdir /ccc
[ -d /ccc ] || mkdir /ccc