Linux的shell脚本

shell是一种脚本语言,那么,就必须有解释器来执行这些脚本

脚本编写格式

#!/bin/bash,脚本的开始必须要添加这一行

# 上面中的 #! 是一种约定标记,他告诉系统这个脚本需要什么样的解释器来执行

变量

变量的定义和变量的提取

shell变量只能以字母开头

定义变量使用小写和大写字母,特殊字符只能是_

变量的名字需要通俗易懂,通过名字就应该大致的知到变量的含义

变量使用小写,可能会与linux命令冲突,尽量使用大写

bash 复制代码
[root@bogon ~]# A=wyz
[root@bogon ~]# echo $A
wyz
bash 复制代码
[root@bogon ~]# a=/etc/hosts
[root@bogon ~]# echo $a
/etc/hosts
[root@bogon ~]# ls $a
/etc/hosts
[root@bogon ~]# cat $a
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

命令替换

将变量定义为一条命令,使用()或者``,就能够将命名定义为一条命令

bash 复制代码
[root@bogon ~]# ip a show ens160 | grep inet | grep ens160| awk '{print $2}' | cut -d'/' -f1
192.168.100.129
[root@bogon ~]# IP=$(ip a show ens160 | grep inet | grep ens160| awk '{print $2}' | cut -d'/' -f1)
[root@bogon ~]# echo $IP
192.168.100.129

特殊变量

特殊变量有$$,$?,$0,$1,2,@,\*,#

:当前进程的ID $`?`:列出上一条命令的执行状态。0:正常执行,非0:执行错误 $0:表示脚本文件的执行路径,大多数情况会列出脚本的名字 $1:表示传给脚本的第一个参数 $2:表示传给脚本的第一个参数 $@和$\*:表示传给脚本的所有参数 $#:表示传给脚本参数的数量 ```bash ## 演示

[root@bogon ~]# echo $$
2900
[root@bogon ~]# ps aux | grep bash
root 2871 0.0 0.1 8688 5524 pts/0 Ss+ 13:54 0:00 -bash
root 2900 0.0 0.1 8688 5492 pts/1 Ss 13:57 0:00 -bash
root 2981 0.0 0.0 6408 2180 pts/1 S+ 14:19 0:00 grep --color=auto bash
[root@bogon ~]#

复制代码
```bash
# 演示$?
[root@bogon ~]# ls
anaconda-ks.cfg  script  text.txt
[root@bogon ~]# echo $?
0
[root@bogon ~]# LL
-bash: LL: command not found
[root@bogon ~]# echo $?
127
bash 复制代码
# 演示$0、$1、$2、$@、$*、$#

写一个简单的脚本,运行一下
#!/bin/bash
echo "File Name: $0"
echo "First Parameter: $1"
echo "second Parameter: $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters: $#"


[root@bogon script]# ./spec-var.sh tes ssd  ad
File Name: ./spec-var.sh
First Parameter: tes
First Parameter: ssd
Quoted Values: tes ssd ad
Quoted Values: tes ssd ad
Total Number of Parameters: 3

脚本的后面有三个参数分别是 tes,ssd和ad,在运行后可以看到

$0:显示了脚本的路径

$1:显示了定义的第一个参数

$2:显示的定义的第一和第二两个参数

@和*:显示了给脚本的所有参数

$#:显示了参数的数量

环境变量

保证系统稳定运行的变量,不能随便改

env可以列出环境变量,不建议更改

bash 复制代码
[root@bogon ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=bogon
PWD=/root
LOGNAME=root
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.m4a=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.oga=01;36:*.opus=01;36:*.spx=01;36:*.xspf=01;36:
SSH_CONNECTION=192.168.100.1 12445 192.168.100.129 22
XDG_SESSION_CLASS=user
SELINUX_ROLE_REQUESTED=
TERM=xterm-256color
LESSOPEN=||/usr/bin/lesspipe.sh %s
USER=root
SELINUX_USE_CURRENT_RANGE=
SHLVL=1
XDG_SESSION_ID=13
XDG_RUNTIME_DIR=/run/user/0
SSH_CLIENT=192.168.100.1 12445 22
DEBUGINFOD_URLS=https://debuginfod.centos.org/ 
which_declare=declare -f
PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
SELINUX_LEVEL_REQUESTED=
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
MAIL=/var/spool/mail/root
SSH_TTY=/dev/pts/1
BASH_FUNC_which%%=() {  ( alias;
 eval ${which_declare} ) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot $@
}
_=/usr/bin/env
OLDPWD=/root/script

shell脚本的条件判断

shell对于缩进没有要求

判断以一条命令是否执行成功

bash 复制代码
#!/bin/bash
ls >> /dev/null
if [ "$?" == 0 ]       ## 执行条件
then
	echo "命令执行成功"  ## 执行命令
else
	echo "命令执行失败"  ## 执行命令
fi

如果上一条命令执行成功,会输出"命令执行成功",如果不成功,会输出"命令执行失败"

bash 复制代码
[root@bogon script]# cat if.sh 
#!/bin/bash
ls >> /dev/null
if [ "$?" == 0 ]
then
        echo "命令执行成功"
else
        echo "命令执行失败"
fi
[root@bogon script]# chmod +x if.sh 
[root@bogon script]# ./if.sh
命令执行成功

bash -x + 脚本,可以列出脚本的执行过程

bash 复制代码
[root@bogon script]# bash -x ./if.sh 
+ ls
+ '[' 0 == 0 ']'
+ echo 命令执行成功
命令执行成功

判断一个文件是否存在

bash 复制代码
#!/bin/bash
if [ -f anaconda-ks.cfg]
then
	echo "file exists"
else
	echo "file not found"
fi
bash 复制代码
[root@bogon script]# cat if1.sh 
#!/bin/bash
if [ -f anaconda-ks.cfg ]
then
        echo "file exists"
else
        echo "file not found"
fi
[root@bogon script]# chmod +x if1.sh 
[root@bogon script]# ./if1.sh 
file exists

shell的与and或

&&:与,就是英文中的and,只有前面的命令正确的执行了,才会执行&&后面的命令

||:或,就是英文中的or,前后两个只要有一个正确,就算正确

&&||被称为逻辑运算

&&:与

命令连接符,只有前面的命令正确的执行了,才会执行&&后面的命令

bash 复制代码
## 两条命令都正确,使用$?查看
[root@bogon script]# ls && ls
anaconda-ks.cfg  hello.sh  if1.sh  if.sh  ping.sh  spec-var.sh
anaconda-ks.cfg  hello.sh  if1.sh  if.sh  ping.sh  spec-var.sh
[root@bogon script]# echo $?
0

## 两条命令只有后面的命令正确,使用$?查看
[root@bogon script]# Ls && ls
-bash: Ls: command not found
[root@bogon script]# echo $?
127

## 两条命令只有前面的命令正确,使用$?查看
[root@bogon script]# ls && Ls
anaconda-ks.cfg  hello.sh  if1.sh  if.sh  ping.sh  spec-var.sh
-bash: Ls: command not found
[root@bogon script]# echo $?
127

## 两条命令都不正确,使用$?查看
[root@bogon script]# Ls && Ls
-bash: Ls: command not found
[root@bogon script]# echo $?
127

就是说只有两个命令都正确,这条命令才算正确

使用 &&连接的多条命令,可以看成是一条命令

||:或

命令连接符,只有前面的命令执行失败错误了,才会执行||后面的命令

bash 复制代码
[root@bogon script]# ls || echo 0
anaconda-ks.cfg  hello.sh  if1.sh  if.sh  ping.sh  spec-var.sh
[root@bogon script]# echo $?
0
[root@bogon script]# Ls || echo 0
-bash: Ls: command not found
0
[root@bogon script]# echo $?
0

shell的条件分支语句(case)

bash 复制代码
#!/bin/bash
echo "Input a number between 1 to 4"
echo "Your number is:\c"
read aNum
case $aNum in
	1) echo 'you select 1';;
	2) echo 'you select 2';;
	3) echo 'you select 3';;
	4) echo 'you select 4';;
	*) echo 'you do not select a number between 1 to 4';;
esac
	

read:可以从用户的输入读取变量,aNum就是指下面的变量$aNum

for循环

bash 复制代码
#!/bin/bash
for i in 1 2 3 4 5  ## 这里也可以写成{1..5}
do
	echo "The value is:$1"
done

循环1到5,并将其输出出来

while循环

bash 复制代码
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 5]
do
	COUNTER=`expr $COUNTER + 1`
	echo $CONTER
done
  • eq:等于(equal)

  • lt:小于(less than)

  • le:小于等于(less equal)

  • gt:大于(greater than)

  • ge:大于等于(greater equal)

  • expr:进行计算的命令,linux中,只有使用了这个命令,才能进行算术运算

bash 复制代码
[root@bogon script]# cat while.sh 
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 5 ]
do
        COUNTER=`expr $COUNTER + 1`
        echo $COUNTER
done
[root@bogon script]# bash while.sh 
1
2
3
4
5
bash 复制代码
#!/bin/bash
while true
do
	sleep 1
	echo "hello word"
done

这种执行建议加上sleep,终止脚本只能通过Ctrl+C

untill循环

主要用于交互式脚本,搭配read语句使用

bash 复制代码
#!/bin/bash
COUNTER=0
until [ $COUNTER -lt 5 ]
do
        COUNTER=`expr $COUNTER + 1`
        echo $COUNTER
done

直到什么条件满足[ $COUNTER -lt 5 ],才会执行

交互式脚本,强制执行某个命令,要不执行,要不退出

bash 复制代码
echo "2"
echo "1"
until [[ "$aNum" =~ ^[1-2]$ ]]   # 以1或2开头,或者以1或2结尾
do
	read -rp " aNum [1-2]: " -e -i 1 aNum  # -e和-i是指默认以后面的1输出
done

Shell脚本函数

bash 复制代码
#!/bin/bash
function check()
{
echo -e "=====================世界你好======================="
}
  • function:定一个函数

  • check:函数名,里面不用加参数,使用的时候直接调用

定义这个函数之后,在下面的代码中只需输入 check,就可以调用这个命令

​​​​一般我们可以将一个函数文件写到一个单独的文件里面,需要时,直接使用source直接调用这个文件

相关推荐
Spring-wind1 小时前
【linux】kill命令
linux
dreamer2921 小时前
21、Tomato
linux·安全·web安全·网络安全·系统安全
小小的木头人2 小时前
Docker vs. containerd 深度剖析容器运行时
运维·docker·容器
Data 3172 小时前
Shell脚本编程基础(二)
大数据·linux·运维·数据仓库·sql·centos·bash
古猫先生2 小时前
YMTC Xtacking 4.0(Gen5)技术深度分析
服务器·人工智能·科技·云计算
青年有志3 小时前
Web 服务器介绍 | 通过 Tomcat 说明其作用
服务器·前端·tomcat
it技术分享just_free3 小时前
基于 K8S kubernetes 的常见日志收集方案
linux·运维·docker·云原生·容器·kubernetes·k8s
bmseven3 小时前
windows远程桌面连接ubuntu
linux·windows·ubuntu
aidroid4 小时前
git github仓库管理
linux·运维·docker
学习3人组4 小时前
集群服务器主机实现主机名与IP绑定
运维·服务器·tcp/ip