什么是Shell
系统跟计算机硬件交互时的中间介质、一个外壳程序统称【bash就是具体的一种Shell】
作用:将用户的指令转发给系统内核,由内核去支配计算机硬件执行操作
为什么要用Shell
有时候要重复执行一些代码,为了方便,写成脚本,可多次重复多条语句
Linux中的Shell
[root@localhost ~] cat /etc/Shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
我们常用的脚本是bash脚本,正常我们用户(包括root)新建的时候默认指定默认Shell为bash
Shell脚本是纯文件,可用任何编辑器编辑,通常以.sh为后缀,以
#!/bin/bash
作为第一行
如果要执行Shell脚本,必须赋予可执行权限
set -e参数表示只要Shell脚本中发生错误,即命令返回值不等于0,则停止执行并退出Shell +e关闭-e选项
set -u参数表示Shell脚本执行时如果遇到不存在的变量会报错并停止执行。
变量
变量=值
输入与输出
read 变量
read -p "" 变量
echo "$变量"
简单案例
判断语句(常与test一起用,用了test就不用括号)
一、if的基本语法:
if [ command ];then
符合该条件执行的语句
elif [ command ];then
符合该条件执行的语句
else
符合该条件执行的语句
fi
二、文件/文件夹(目录)判断
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
**[ -d DIR ] 如果 FILE 存在且是一个目录则为真。
**[ -e FILE ] 如果 FILE 存在则为真。
**[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。(同-h)
[ -N FILE ] 如果 FILE 存在且自从上次读已被改动则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 要新, 或者 FILE1 存在且 FILE2 不存在则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号(相同的文件)则为真。
三、字符串判断
[ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
[ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
[ STRING1 = STRING2 ] 如果两个字符串相同则为真;(单个=且等号左右要有空格)
[ STRING1 != STRING2 ] 如果字符串不相同则为真;
[ STRING1 ] 如果字符串不为空则为真,与-n类似
四、数值判断
INT1 -eq INT2 INT1和INT2两数相等为真 ,=
INT1 -ne INT2 INT1和INT2两数不等为真 ,<>
INT1 -gt INT2 INT1大于INT1为真 ,>
INT1 -ge INT2 INT1大于等于INT2为真,>=
INT1 -lt INT2 INT1小于INT2为真 ,<</div>
INT1 -le INT2 INT1小于等于INT2为真,<=
五、复杂逻辑判断(优先级为: ! > -a > -o)
-a 与
-o 或
! 非
exp1: 如果a>b且a
if (( a > b )) && (( a < c ))
或者
if [[ $a > $b ]] && [[ $a < $c ]]
或者
if [ $a -gt $b -a $a -lt $c ]
exp2:如果a>b或a
if (( a > b )) || (( a < c ))
或者
if [[ $a > $b ]] || [[ $a < $c ]]
或者
if [ $a -gt $b -o $a -lt $c ]
"||"和"&&"在Shell里可以用,也就是第一个写成if [ a>b && a ]
脚本案例——输出文件是否存在+文件类型+文件拥有者权限
#!/bin/bash
#Program
# User input a filename, program will check the flowing;
# 1)exist? 2) file/directory? 3) file permissions
echo -e "Please input a filename I will check the filename's type and\
permission.\n "
read -p "Please input a filename: " filename
test -z $filename && echo "You Must input a filename." && exit 0
test ! -e $filename && echo "The filename '$filename' Do Not exist" && exit 0
test -f $filename && filetype="regular file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writeable"
test -x $filename && perm="$perm excutable"
echo "The filename: $filename is a $filetype"
echo "And the permissions are : $perm"
循环语句
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
函数应用
while condition
do
command
done
案例欣赏
- Docker(xiandian2.2版本)一键安装server端
# !/bin/bash
# chkconfig:2345 60 30
# FileName:docker-server.sh
# serverIP(registry)
export server_ip=192.168.100.10
# clientIP
export client_ip=192.168.100.20
# NETMASK
export netmask=255.255.255.0
# GATEWAY
export gateway=192.168.100.2
# INTERFACE
export device=eno16777736
# CENTOS
export local=/opt/centos
# DOCKER
export docker=/opt/docker
# HOSTNAME
hostnamectl set-hostname server
# hosts
if test "`grep "server" /etc/hosts`" = ""
then
echo -e "$server_ip server" > /dev/null 2>&1 >> /etc/hosts
else
sed -i "s/.* server/$server_ip server/g" /etc/hosts
fi
if test "`grep "client" /etc/hosts`" = ""
then
echo -e "$client_ip client" > /dev/null 2>&1 >> /etc/hosts
else
sed -i "s/.* client/$client_ip client/g" /etc/hosts
fi
# FIREWALLD
systemctl stop firewalld.service
systemctl disable firewalld.service
# SELINUX
sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
# IPTABLES
iptables -F
iptables -X
iptables -Z
/usr/sbin/iptables-save
# NETWORK
if test "`grep "IPADDR" /etc/sysconfig/network-scripts/ifcfg-$device`" = ""
then
echo -e "IPADDR=$server_ip" > /dev/null 2>&1 >> /etc/sysconfig/network-scripts/ifcfg-$device
else
sed -i "s/IPADDR=.*/IPADDR=$server_ip/g" /etc/sysconfig/network-scripts/ifcfg-$device
fi
if test "`grep "NETMASK" /etc/sysconfig/network-scripts/ifcfg-$device`" = ""
then
echo -e "NETMASK=$netmask" > /dev/null 2>&1 >> /etc/sysconfig/network-scripts/ifcfg-$device
else
sed -i "s/NETMASK=.*/NETMASK=$netmask/g" /etc/sysconfig/network-scripts/ifcfg-$device
fi
if test "`grep "GATEWAY" /etc/sysconfig/network-scripts/ifcfg-$device`" = ""
then
echo -e "GATEWAY=$gateway" > /dev/null 2>&1 >> /etc/sysconfig/network-scripts/ifcfg-$device
else
sed -i "s/GATEWAY=.*/GATEWAY=$gateway/g" /etc/sysconfig/network-scripts/ifcfg-$device
fi
if test "`grep "DNS1" /etc/sysconfig/network-scripts/ifcfg-$device`" = ""
then
echo "DNS1=8.8.8.8" > /dev/null 2>&1 >> /etc/sysconfig/network-scripts/ifcfg-$device
else
sed -i 's/DNS1=.*/DNS1=8.8.8.8/g' /etc/sysconfig/network-scripts/ifcfg-$device
fi
sed -i 's/BOOTPROTO=.*/BOOTPROTP=static/g' /etc/sysconfig/network-scripts/ifcfg-$device
sed -i 's/ONBOOT=.*/ONBOOT=yes/g' /etc/sysconfig/network-scripts/ifcfg-$device
service network restart
if test $? != 0
then
echo "NetWork Restart Faild"
exit 1
fi
# local.repo
touch /etc/yum.repos.d/local.repo
echo -e "[centos]\nname=centos\nbaseurl=file://$local\nenabled=1\ngpgcheck=0\n[docker]\nname=docker\nbaseurl=file://$docker\nenabled=1\ngpgcheck=0" > /dev/null 2>&1 > /etc/yum.repos.d/local.repo
# FTP
mount -o loop /opt/CentOS-7-x86_64-DVD-1511.iso $local
# \mv /etc/yum.repos.d/CentOS-* /media/
yum -y install vsftpd
yum -y install ftp
echo -e "\nanon_root=/opt" >> /dev/null 2>&1 >> /etc/vsftpd/vsftpd.conf
service vsftpd restart
systemctl enable vsftpd
# NET
if test "`grep "net.ipv4.ip_forward" /etc/sysctl.conf`" = ""
then
echo "net.ipv4.ip_forward = 1" > /dev/null 2>&1 >> /etc/sysctl.conf
else
sed -i 's/net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
fi
if test "`grep "net.ipv4.conf.default.rp_filter" /etc/sysctl.conf`" = ""
then
echo "net.ipv4.conf.default.rp_filter = 0" > /dev/null 2>&1 >> /etc/sysctl.conf
else
sed -i 's/net.ipv4.conf.default.rp_filter.*/net.ipv4.conf.default.rp_filter = 0/g' /etc/sysctl.conf
fi
if test "`grep "net.ipv4.conf.all.rp_filter" /etc/sysctl.conf`" = ""
then
echo "net.ipv4.conf.all.rp_filter = 0" > /dev/null 2>&1 >> /etc/sysctl.conf
else
sed -i 's/net.ipv4.conf.all.rp_filter.*/net.ipv4.conf.all.rp_filter = 0/g' /etc/sysctl.conf
fi
sysctl -p
# UNAME
yum -y upgrade
if test $? = 0
then
# AutoLogin
\rm /etc/systemd/system/getty.target.wants/getty@tty1.service
\cp /lib/systemd/system/getty@.service /etc/systemd/system/getty@tty1.service
sed -i 's/ExecStart=.*/ExecStart=-\/sbin\/agetty --autologin root --noclear %I/g' /etc/systemd/system/getty@tty1.service
echo ";Alias=getty@tty1.service" > /dev/null 2>&1 >> /etc/systemd/system/getty@tty1.service
ln -s /etc/systemd/system/getty@tty1.service /etc/systemd/system/getty.target.wants/getty@tty1.service
# AutoStart
mv /root/docker-server.sh /root/start.sh
mv /root/docker-server-after.sh /root/docker-server.sh
echo -e "mount -o loop /opt/CentOS-7-x86_64-DVD-1511.iso $local\nsystemctl start vsftpd\nservice network restart" > /dev/null 2>&1 > /root/start.sh
echo "/root/start.sh" > /dev/null 2>&1 >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
chmod +x /root/start.sh
else
echo "upgrade false"
exit 1
fi
# centos——dir-exsit ?
if test "`curl ftp://localhost | grep centos`" = ""
then
echo -e "Dictionary centos not found !\nSystem will reboot after 5 seconds !"
sleep 5
reboot
fi
# docker——dir-exsit ?
if test "`curl ftp://localhost | grep docker`" = ""
then
echo -e "Dictionary docker not found !\nSystem will reboot after 5 seconds !"
sleep 5
reboot
fi
ans=y
printf "Please confirm client have finshed !(y)"
read ans
if test "$ans" = "y"
then
reboot
else
echo "Please reboot after client finshed !"
fi
- Docker用来push镜像的脚本
# !/bin/bash
# kconfig:2345 60 30
# FileName:push.sh
# Server(Registry)
export server_ip=192.168.200.102
export client_ip=192.168.200.103
echo "Test connecting to client"
scp /etc/hosts $client_ip:/etc/hosts
touch pull.sh
echo -e "# !/bin/bash\n# kconfig:2345 60 30\n# FileName:pull.sh\n# Client\nexport server_ip=$server_ip\nexport client_ip=$client_ip" > /dev/null 2>&1 >> pull.sh
for tar in `ls *.tar`
do
echo -e "docker pull `ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/_[v,0-9].*\|latest\|_ho.*//g' | sed 's/_/\//g'`:`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/.*_//g'`" > /dev/null 2>&1 >> pull.sh
if [[ "`docker images | awk '{print $1":"$2}'`" =~ "`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/_[v,0-9].*\|latest\|_ho.*//g' | sed 's/_/\//g'`:`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/.*_//g'`" ]]
then
echo -e "\n\033[34;1m`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/_[v,0-9].*\|latest\|_ho.*//g' | sed 's/_/\//g'`:`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/.*_//g'` has been pushed .\033[0m\n"
else
docker load -i $tar
if test $? != 0
then
echo -e "\n\033[31;1mLoad $tar faild .\033[0m\n"
else
echo -e "\n\033[36;1mLoad $tar success .\033[0m\n"
image_id=`docker images | grep -w '<none>' | awk '{print $3}'`
docker tag $image_id $server_ip:5000/`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/_[v,0-9].*\|latest\|_ho.*//g' | sed 's/_/\//g'`:`ls $tar | sed 's/.tar//g' | sed 's/:/_/g' | sed 's/-n/_n/g' | sed 's/.*_//g'`
if test $? != 0
then
echo -en "\n\033[31;1mTag $tar faild .\nPlease input your tag :\n$server_ip:5000/\033[0m"
read tag
docker tag $image_id $server_ip:5000/$tag
if test $? != 0
then
echo -e "\n\033[31;1mYour tag is not available , we will delete it .\033[0m\n"
docker rmi -f `docker images | awk '/<none>/{print $3}'` > /dev/null 2>&1
else
echo -e "\n\033[36;1mTag $tar success .\033[0m\n"
docker push `docker images | grep $image_id | awk '{print$1,$2}' | sed 's/ /:/g'`
if test $? != 0
then
echo -e "\n\033[31;1mPush $tar faild .\033[0m\n"
else
echo -e "\n\033[36;1mPush $tar success .\033[0m\n"
fi
fi
else
echo -e "\n\033[36;1mTag $tar success .\033[0m\n"
docker push `docker images | grep $image_id | awk '{print$1,$2}' | sed 's/ /:/g'`
if test $? != 0
then
echo -e "\n\033[31;1mPush $tar faild .\033[0m\n"
else
echo -e "\n\033[36;1mPush $tar success .\033[0m\n"
fi
fi
fi
fi
done
echo -e "\n\033[33;1mDocker images : \033[0m\n"
docker images
echo "echo -e \"\n\033[33;1mDocker images : \033[0m\n\"" > /dev/null 2>&1 >> pull.sh
echo "docker images" > /dev/null 2>&1 >> pull.sh
echo -e "\n\033[33;1mDocker insecure registry : \033[0m\n"
curl http://$server_ip:5000/v2/_catalog | python -mjson.tool
echo "echo -e \"\n\033[33;1mDocker insecure registry : \033[0m\n\"" > /dev/null 2>&1 >> pull.sh
echo "curl http://$server_ip:5000/v2/_catalog | python -mjson.tool" > /dev/null 2>&1 >> pull.sh
scp pull.sh $client_ip:/root/pull.sh
ssh $client_ip "bash pull.sh;rm -f pull.sh"
if test $? != 0
then
rm -f $0
fi
rl http://KaTeX parse error: Can't use function '\"' in math mode at position 63: … echo "echo -e \̲"̲\n\033[33;1mDoc…server_ip:5000/v2/_catalog | python -mjson.tool" > /dev/null 2>&1 >> pull.sh
scp pull.sh $client_ip:/root/pull.sh
ssh $client_ip “bash pull.sh;rm -f pull.sh”
if test $? != 0
then
rm -f $0
fi