Shell脚本编写

基础教程

参考:https://blog.csdn.net/w918589859/article/details/108752592

一、shell的分类

#!/bin/bash				[指定告知系统当前这个脚本要使用的shell解释器]
Shell相关指令

文件命名规范: 文件名.sh .sh是linux下bash shell 的默认后缀。

输入输出重定向

linux 的标准输入与输出。

设备设备名文件描述符类型
键盘/dev/stdin0标准输入
显示器/dev/stdout1标准输出
显示器/dev/stderr2标准错误输出
1、输入重定向

输入重定向就是不使用标准输入端口输入文件,而是使用指定的文件作为标准输入设备。

类型符号(语法)功能
标准输入命令<文件1命令把文件1的内容作为标准输入设备
标识符限定输入命令<<标识符命令把标准输入中读入内容,直到遇到“标识符”分解符为止
输入输出重定向(同时使用)命令< 文件1 >文件2命令把文件1的内容作为标准输入,把文件2作为标准输出。
2、输出重定向

把要输出的文件信息写入到一个文件中去,而不是将要输出的文件信息输出到控制台(显示屏)。

&表示全部文件,文件不管对错,1表示标准输出文件,2表示标准错误输出。

类型符号作用
标住输出重定向命令 > 文件覆盖方式,把命令的正确输出内容输出到指定的文件或设备当中
标住输出重定向命令 >> 文件追加方式,把命令的正确输出内容输出到指定的文件或设备当中
标准错误输出重定向错误命令2 > 文件以覆盖方式,把命令的错误输出输出到指定的文件或设备当中
标准错误输出重定向错误命令2 >> 文件以追加方式,把命令的错误输出输出到指定的文件或设备当中
正确输出和错误输出同时保存命令 > 文件 2>&1以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
正确输出和错误输出同时保存命令 >> 文件 2>&1以追加的方式,把正确输出和错误输出都保存到同一个文件当中。
正确输出和错误输出同时保存命令 &> 文件以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
正确输出和错误输出同时保存命令 &>> 文件以追加的方式,把正确输出和错误输出都保存到同一个文件当中。
正确输出和错误输出同时保存命令 >> 文件1 2>>文件2把正确的输出追加到文件1中,把错误的输出追加到文件2中。

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到dev/null

[root@localhost ~]$  command > dev/null

脚本的执行

1、多命令执行
多命令执行符作用格式
命令1 ;命令2多个命令顺序执行,命令之间没有任何逻辑联系
&&命令1 && 命令2当命令1正确执行( ? = 0 ), 则 命令2才会执行;
当命令1执行不正确( ? ≠ 0),则命令2不会执行。
||命令1 || 命令2当命令1正确执行( ? = 0),则命令2不会执行;
当命令1执行不正确( ? ≠ 0 ),则命令2才会执行。
2、执行方式
[root@localhost ~]$ vim test.sh
#!/bin/bash
echo “hello world”

①、给文件增加执行权限

[root@localhost ~]$ chmod u+x test.sh
[root@localhost ~]$ ./test.sh  #绝对路径或相对路径执行

②、通过Bash调用执行脚本

[root@localhost ~]$ bash test.sh

二、变量

1、命名规则

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 等号左右两侧不能有空格,可以使用下划线“_”,变量的值如果有空格,需要使用单引号双引号包括。如:“test=“hello world!””。其中双引号"括起来的内容$(和反引号`都拥有特殊含义,而单引号'括起来的内容都是普通字符。
  • 不能使用标点符号,不能使用bash里的关键字(可用help命令查看保留关键字)。
  • 环境变量建议大写,便于区分
  • 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含"变量名"或用${变量名}包含变量名。
[root@localhost ~]$ test=123
[root@localhost ~]$ test="$test"456
[root@localhost ~]$ echo $test
123456
#叠加变量test,变量值变成了123456
[root@localhost ~]$ test=${test}789
[root@localhost ~]$ echo $test
123456789
#再叠加变量test,变量值编程了123456789

双引号能够识别变量,双引号能够实现转义(类似于“*”)
单引号是不能识别变量,只会原样输出,单引号是不能转义的

2、特殊符号

符号作用
’ ’单引号。在单引号中所有的特殊符号,如“$”和”(反引号)都没有特殊含义。单引号括起来的都是普通字符,会原样输出
“ ”双引号。在双引号中特殊符号都没有特殊含义,但是“$”,"`"(esc键下面)和“\”是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。
· ·反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。和( ) 作 用 一 样 , 不 过 推 荐 使 用 ()作用一样,不过推荐使用()作用一样,不过推荐使用(),因为反引号非常容易看错。
$()和反引号作用一样,用来引用系统命令。(推荐使用)
()用于一串命令执行时,()中的命令会在子Shell中运行
{}用于一串命令执行时,{ }中的命令会在当前Shell中执行。也可以用于变量变形与替换。
[ ]用于变量的测试。

双引号能够识别变量,双引号能够实现转义(类似于“*”)
单引号是不能识别变量,只会原样输出,单引号是不能转义的

[root@localhost ~]$ name=sc
[root@localhost ~]$ echo '$name'
$name
[root@localhost ~]$ echo "$name"
sc

[root@localhost ~]$ echo `date`
2018年10月21日星期一18:16:33 CST
#反引号括起来的命令会正常执行
[root@localhost ~]$ echo '`date`'
`date`
#但是如果反引号命令被单引号括起来,那么这个命令不会执行,
#―date`会被当成普通字符输出
[root@localhost ~]$ echo "`date'"
2018年10月21日星期一18:14:21 CST
#如果是双引号括起来,那么这个命令又会正常执行

[root@localhost ~]$ echo ls
ls
#如果命令不用反引号包含,命令不会执行,而是直接输出
[root@localhost ~]$ echo `ls`
anaconda-ks.cfginstall.loginstall.log.syslog sh test testfile
#只有用反引号包括命令,这个命令才会执行
[root@localhost ~]$ echo $(date)
2018年10月21日星期一18:25:09 CST
#使用$(命令)的方式也是可以的

3、变量的分类

  • 用户自定义变量:自由定义变量名和变量的值。
  • 环境变量:保存的是和系统操作环境相关的数据。
  • 位置参数变量: 这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
  • 预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。
①、用户变量
# 变量定义
name=sc

# 变量调用
echo $name

# 变量查看
set [选项]
选项:
-u:如果设定此选项,调用未声明变量时会报错(默认无任何提示)
-x:如果设定此选项,在命令执行之前,会把命令先输出一次
+<参数> :取消某个set曾启动的参数。

# 直接使用set 命令,会查询系统中所有的变量,包含用户自定义变量和环境变量
set
BASH=/bin/bash
…省略部分输出…
name='shen chao'

# 变量删除
unset 变量名
②、环境变量
# 环境变量设置
# 使用export声明的变量即是环境变量
export age="18"

# 环境变量查询和删除
# (set命令可以查看所有变量,而env命令只能查看环境变量)
unset gender   #删除环境变量gender
env | grep gender

# 系统默认环境变量
env
(..输出..)
HOSTNAME=localhost.localdomain      #主机名
SHELL=/bin/bash                     #当前的shell
TERM=linux                          #终端环境
HISTSIZE=1000                       #历史命令条数
SSH_CLIENT=192.168.4.1594824 22     #当前操作环境是用ssh连接的,这里记录客户端ip
SSH_TTY=/dev/pts/1                  #ssh连接的终端时pts/1
USER=root                           #当前登录的用户
③、位置参数变量
位置参数变量作用
$nn为数字,$0表示当前 Shell 脚本程序的名称,$1-9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 需 要 用 大 括 号 包 含 , 如 9代表第一到第九个参数,十以上的参数需要用大括号包含,如9代表第一到第九个参数,十以上的参数需要用大括号包含,如{10}
$*这个变量代表命令行中所有的参数,$把所有的参数看成一个整体
$@这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
$#这个变量代表命令行中所有参数的个数

$1 是你给你写的shell脚本传的第一个参数,$2 是你给你写的shell脚本传的第二个参数…

[root@localhost sh]$ vim test.sh
#!/bin/sh
echo "shell脚本本身的名字: $0"
echo "传给shell的第一个参数: $1"
echo "传给shell的第二个参数: $2"

输入 bash Test.sh 1 2

shell脚本本身的名字: Test.sh
传给shell的第一个参数: 1
传给shell的第二个参数: 2

$*会把接收的所有参数当成一个整体对待,而$@则会区分对待接收到的所有参数


[root@localhost sh]$ vi parameter2.sh
#!/bin/bash
for i in"$*"
#定义for循环,in后面有几个值,for会循环多少次,注意“$*”要用双引号括起来
#每次循环会把in后面的值赋予变量i
#Shell把$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
	do
		echo "The parameters is: $i"
		#打印变量$i的值
	done


x=1
#定义变量x的值为1
for y in"$@"
#同样in后面的有几个值,for循环几次,每次都把值赋予变量y
#可是Shel1中把“$@”中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
	do
		echo "The parameter$x is: $y"
		#输出变量y的值
		x=$(( $x +1 ))
		#然变量x每次循环都加1,为了输出时看的更清楚
	done

④、预定义变量
预定义变量作用
$#传递到脚本或函数的参数个数
$?最后一次执行的命令的返回状态。
如果这个变量的值为0,证明上一个命令正确执行;
如果这个变量的值为非О(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。
$$当前进程的进程号(PID)
$!后台运行的最后一个进程的进程号(PID)

例子 $?

# 命令正确
root@VM-12-4-ubuntu:~# 1 || ls
1: command not found
1  dir.dir  dontstarvetogether_dedicated_server  Steam  steamcmd
root@VM-12-4-ubuntu:~# echo $?
0

# 命令错误
root@VM-12-4-ubuntu:~# 1 && ls
1: command not found
root@VM-12-4-ubuntu:~# echo $?
127

例子 $$ 和 $!

[root@localhost sh]$ vi variable.sh
#!/bin/bash
echo "The current process is $$"
#输出当前进程的PID.
#这个PID就是variable.sh这个脚本执行时,生成的进程的PID
find /root -name hello.sh &
#使用find命令在root目录下查找hello.sh文件
#符号&的意思是把命令放入后台执行,工作管理我们在系统管理章节会详细介绍
echo "The last one Daemon process is $!"
#输出这个后台执行命令的进程的PID,也就是输出find命令的PID号

⑤、只读变量
#语法:readonly 变量名
a=10
readonly a
a=20   #会报错readonly variable

4、接收键盘输入

read [选项][变量名]

  • 选项:
    -a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。
    -p: “提示信息”:在等待read输入时,输出提示信息
    -t: 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间
    -n: 数字:read命令只接受指定的字符数,就会执行
    -s: 隐藏输入的数据,适用于机密信息的输入
    -d: 后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志。
    -e: 在输入的时候可以使用命令补全功能。

  • 变量名:
    变量名可以自定义,如果不指定变量名,会把输入保存入默认变量REPLY.
    如果只提供了一个变量名,则整个输入行赋予该变量.
    如果提供了一个以上的变量名,则输入行分为若干字,一个接一个地赋予各个变量,而命令行上的最后一个变量取得剩余的所有字

例子

[root@localhost sh]$ vi read.sh
#!/bin/bash

read -t 30 -p "Please input your name: " name
#提示“请输入姓名”并等待30 秒,把用户的输入保存入变量name 中
echo "Name is $name"
#看看变量“$name”中是否保存了你的输入

read -s -t 30 -p "Please enter your age: " age
#提示“请输入年龄”并等待30秒,把用户的输入保存入变量age中
#年龄是隐私,所以我们用“-s”选项隐藏输入
echo -e "\n"
#调整输出格式,如果不输出换行,一会的年龄输出不会换行
echo "Age is $age"

read -n 1 -t 30 -p "Please select your gender[M/F]:" gender
#提示“请选择性别”并等待30秒,把用户的输入保存入变量gender
#使用“-n1”选项只接收一个输入字符就会执行(都不用输入回车)
echo -e "\n"
echo "Sex is $gender"

三、运算符

在shell中,运算符和其他编程脚本语言一样,常见的有算术运算符、关系运算符、逻辑运算符、字符串运算符、文件测试运算符等。

1、算术运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

#!/bin/bash
# 1、完整的表达式要被 ` ` 包含
# 2、表达式和运算符之间要有空格
val=`expr 2 + 2`
echo "两数之和为 : $val"

常用的算术运算符:
+加法 -减法 *乘法 /除法 %取余 =赋值 ==相等 !=不相等

条件表达式要放在方括号之间,并且要有空格,必须写成 [ $a == $b ]

#判断是否相等
if [ $a == $b ]
then
	echo 'a等于b'
else
	echo 'a不等于b'
fi

2、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
假定变量 a 为 10,变量 b 为 20:

运算符单词说明举例
-eqequal检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
-nenot equal检测两个数是否相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gtgreat than检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-ltless than检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-gegreat than or equal检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-leless than or equal检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。
[root@localhost ~]$ [ 10 -gt 10 ] 
[root@localhost ~]$ echo $? 
 1
[root@localhost ~]$ [ 10 -eq 10 ] 
[root@localhost ~]$ echo $? 
 0

3、逻辑运算符

假定变量 a 为 10,变量 b 为 20

运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ]返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

4、字符串运算符

a 为 “abc”,变量 b 为 “efg”

运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否为0,不为0返回 true。[ -n $a ] 返回 true。
str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

5、文件测试运算符

文件测试运算符用于检测 Unix/Linux 文件的各种属性。

操作符说明举例
-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。
-c file检测文件是否是字符设备文件,如果是,则返回 true。[ -c $file ] 返回 false。
-d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。
-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。
-p file检测文件是否是有名管道,如果是,则返回 true。[ -p $file ] 返回 false。
-u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。
-r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。
-w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。
-x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。
-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

注意:权限几个判断,如果只有一个部分符合,则认为是有权限的。

四、函数

所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分

[ function ] funname [()]
{
    action;
    [return int;]
}
  1. 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
  2. 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
#输出结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
#输出结果:
这个函数会对输入的两个数字进行相加运算...
输入第一个数字: 
1
输入第二个数字: 
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !

五、流程控制

1、if条件判断

单分支if条件

if [ 条件判断式 ]
	then
		程序
fi

DIR="/media/cdrom"
if [ ! -e $DIR ]
then
	mkdir -p $DIR
fi
echo "$DIR 创建成功"

双分支if条件语句

if [ 条件判断式 ]
	then
		条件成立时,执行的程序
	else
		条件不成立时,执行的另一个程序
fi

多分支if条件语句

if [ 条件判断式1 ]
	then
		当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
	then
		当条件判断式2成立时,执行程序2
…省略更多条件…
else
	当所有条件都不成立时,最后执行此程序
fi

2、多分支case条件语句


case $变量名 in
	"值1")
	如果变量的值等于值1,则执行程序1
	;;
	"值2")
	如果变量的值等于值2,则执行程序2
	::
	…省略其他分支…
	*)
	如果变量的值都不是以上的值,则执行此程序
	;;
esac

3、for循环

for 变量 in 值1 值2 值3 …(可以是一个文件等)
	do
		程序
	done
	
	这种语法中for循环的次数,取决于in后面值的个数(空格分隔),有几个值就循环几次,并且每次循环都把值赋予变量。
	也就是说,假设in后面有三个值,for会循环三次,第一次循环会把值1赋予变量,第二次循环会把值2赋予变量,以此类推。


for (( 初始值;循环控制条件;变量变化 ))
	do
		程序
	done
	
语法二中需要注意:
初始值:在循环开始时,需要给某个变量赋予初始值,如i=1;

循环控制条件:用于指定变量循环的次数,如i<=100,则只要i的值小于等于100,循环就会继续;

变量变化:每次循环之后,变量该如何变化,如i=i+1。代表每次循环之后,变量i的值都加1。

4、while循环

while [ 条件判断式 ]
	do
		程序
	done


1加到100
while [ $i -le 100 ]
#如果变量i的值小于等于100,则执行循环
	do
		s=$(( $s+$i ))
		i=$(( $i+1 ))
	done
echo "The sum is: $s"

5、until循环

和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

until [ 条件判断式 ]
	do
		程序
	done

1加到100
until [ $i -gt 100 ]
#循环直到变量i的值大于100,就停止循环
	do
		s=$(( $s+$i ))
		i=$(( $i+1 ))
	done
echo "The sum is: $s"

6、特殊流程控制语句

①、exit语句

系统是有exit命令的,用于退出当前用户的登录状态。
可是在Shell脚本中,exit语句是用来退出当前脚本的。
也就是说,在Shell脚本中,只要碰到了exit语句,后续的程序就不再执行,而直接退出脚本。
exit [返回值]

②、break语句

当程序执行到break语句时,会结束整个当前循环。而continue 语句也是结束循环的语句,不过continue 语句单次当前循环,而下次循环会继续。
break

六、字符截取、替换和处理命令

1、正则表达式

元字符描述示例
\转义符,将特殊字符进行转义,忽略其特殊意义a.b匹配a.b,但不能匹配ajb,.被转义为特殊意义
^匹配行首,awk中,^则是匹配字符串的开始^tux匹配以tux开头的行
$匹配行尾,awk中,$则是匹配字符串的结尾tux$匹配以tux结尾的行
.匹配除换行符\n之外的任意单个字符ab.匹配abc或bad,不可匹配abcd或abde,只能匹配单字符
[ ]匹配包含在[字符]之中的任意一个字符coo[kl]可以匹配cook或cool
[^]匹配[^字符]之外的任意一个字符123[^45]不可以匹配1234或1235,1236、1237都可以
[-]匹配[]中指定范围内的任意一个字符,要写成递增[0-9]可以匹配1、2或3等其中任意一个数字
?匹配之前的项1次或者0次colou?r可以匹配color或者colour,不能匹配colouur
+匹配之前的项1次或者多次sa-6+匹配sa-6、sa-666,不能匹配sa-
*匹配之前的项0次或者多次co*l匹配cl、col、cool、coool等
()匹配表达式,创建一个用于匹配的子串ma(tri)?匹配max或maxtrix
{n}匹配之前的项n次,n是可以为0的正整数[0-9]{3}匹配任意一个三位数,可以扩展为[0-9][0-9][0-9]
{n,}之前的项至少需要匹配n次[0-9]{2,}匹配任意一个两位数或更多位数不支持{n,}{n,}{n,}
{n,m}指定之前的项至少匹配n次,最多匹配m次,n<=m[0-9]{2,5}匹配从两位数到五位数之间的任意一个数字
|交替匹配两边的任意一项ab(c|d)匹配abc或abd

2、字符截取、替换命令

①、cut 列提取命令
[root@localhost ~]$ cut [选项] 文件名
选项:
-f 列号: 提取第几列
-d 分隔符: 按照指定分隔符分割列
-n	取消分割多字节字符
-c 字符范围: 不依赖分隔符来区分列,而是通过字符范围(行首为0)来进行字段提取。“n-”表示从第n个字符到行尾;“n-m”从第n个字符到第m个字符;“一m”表示从第1个字符到第m个字符。
--complement	补足被选择的字节、字符或字段
--out-delimiter	指定输出内容是的字段分割符
②、awk 编程

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。

(内容太多了。。看原文吧)

实用命令

1、判断用户是否存在

# wc -l 计算行数
cat /etc/passwd | grep 用户名 | wc -l

2、在当前目录压缩某目录文件

# 先进入目录再压缩
# 压缩名 源文件
cd 111 && tar zcvf 222.tar.gz 222

3、授权

#授予执行权限
chmod u+x 1.sh

4、在shell脚本中判断上一条命令是否执行成功

#!/bin/bash
 
# 这里是要被判断执行状态的命令(成功或者失败)
some command 
 
# 这里是判断上条命令是否执行成功的语句块
if [ $? -eq 0 ]; then
    echo "succeed"
else
    echo "failed"
fi
 
# linux 命令中,如果命令执行成功,则 $?值为 0,否则不为 0.
# -eq 等于
# -ne 不等于
# -gt 大于
# -lt 小于
# -ge 大于等于
# -le 小于等于

一些Bug

1、报 nohup: redirecting stderr to stdout 错误

#原命令
nohup sh /test/test.sh >/test/nohup.out &

#改为
nohup sh /test/test.sh >/test/nohup.out 2>&1 &

实例

startup.sh

#!/bin/bash

jar_home="/yiyu/project/SpringBoot/store/"
jar_name="store-0.0.1-SNAPSHOT.jar"

log_home="/yiyu/project/SpringBoot/store/"
log_name="store-log.txt"

nohup java -jar ${jar_home}${jar_name} >${log_home}${log_name} 2>&1 &

# 这里是判断上条命令是否执行成功的语句块
if [ $? -eq 0 ]; then
    echo "${jar_name} succeed"
else
    echo "${jar_name} failed"
fi

shutdown.sh

#!/bin/bash


jar_home="/yiyu/project/SpringBoot/store/"
jar_name="store-0.0.1-SNAPSHOT.jar"
pid="123456"

#获取进程pid
#echo "正在获取进程: ${jar_name} pid "
pid=`ps -ef|grep ${jar_name}|grep -v grep|awk '{print $2}'`

if [ $? -eq 0 ]; then
    echo "获取进程 ${jar_name} pid 成功 :${pid}"
else
    echo "获取进程 ${jar_name} pid 失败"
	exit 1
fi

#杀死进程
kill -9 ${pid}

# 这里是判断上条命令是否执行成功的语句块
if [ $? -eq 0 ]; then
    echo "杀死进程 ${jar_name} succeed"
else
    echo "杀死进程 ${jar_name} failed"
fi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值