1.shell的执行方式
- 方式1:
bash file
- 方式2:
sh file
- 方式3:
source file
- 方式4:
. file
- 方式5:
./file
(需要使用chmod +x file
进行授权)tips:
- 文件名是否包含
.sh
后缀不影响运行- shell文件的开头需要加上
#!/bin/bash
表示使用shell解释器- 在当前shell中输入
bash
会创建一个子shell并进入该shell,此时使用exit
退出的是子shell- 方式1和2会开一个子shell运行脚本(运行完后该子shell会被删除),方式3和4会在当前shell运行脚本:
#---------test.sh------------ cd /home ls #---------test.sh------------ bash test.sh / sh test.sh # 使用这两种方式执行脚本后当前路径还是原始路径,因为脚本是在子shell中执行 source test.sh / . test.sh # 使用这两种方式执行脚本后当前路径切换到/home,因为脚本是在当前shell中执行
- 查询shell解释器的位置可以使用命令:
cat /etc/shells
2. 自定义变量
- 定义变量:变量名=变量值,比如
a='psj'
或者a="psj"
- 等号左右没有空格
- 变量名不能以数字开头
- 变量值如果有空格,必须用引号(可以单引号)包含
- 在已有变量对应的变量值进行叠加:
a=${a}w
或者a="$a"w
(必须使用双引号),echo $a
输出psjw
,如果写为a=$aw
会将aw
视为一个变量- 变量名只能以英文开头(不同于Java可以以下划线开头)
- 引用变量:
$变量名
或者${变量名}
- 变量查看:
set
- 变量删除:
unset 变量名
(将当前shell的变量删除)- 交互定义变量:
read 变量名
表示从键盘读入变量值,如下代码:# --------bash内容----------- read -p "输入:" name echo $name # -------执行bash--------- [root@VM-0-17-centos ~]# bash test.sh 输入:psj psj
tips:
shell编程中单引号、双引号和反引号的区别?如下代码,使用了单引号则
$name
将失去原有的变量内容(强引用),仅为一般字符的显示型态;使用双引号仍然可以保有变量的内容(弱引用);反引号中的字符串将解释成shell命令来执行:# -----------双引号------------ [root@VM-0-17-centos ~]# name=psj [root@VM-0-17-centos ~]# a="hello \$name" [root@VM-0-17-centos ~]# echo $a hello psj # -----------单引号------------ [root@VM-0-17-centos ~]# a='hello $name' [root@VM-0-17-centos ~]# echo $a hello $name # -----------反引号------------ [root@VM-0-17-centos ~]# s=date [root@VM-0-17-centos ~]# echo $s date [root@VM-0-17-centos ~]# s=`date` [root@VM-0-17-centos ~]# echo $s Sun Feb 6 15:16:43 CST 2022 [root@VM-0-17-centos ~]# s="`date` 123" [root@VM-0-17-centos ~]# echo $s Sun Feb 6 15:20:01 CST 2022 123
shell编程中&&表示前面的命令成功就会执行后面的命令;||表示前面的命令失败就会执行后面的命令(如果前面命令成功就不会执行后面的命令)。所以在shell编程中三目表达式可以写为:
判断语句 && 为真时执行的语句 || 为假时执行的语句
3.整数运算
expr:
expr $num1 + $num2
或者expr 1 + 2
- 表达式之间一定要有空格:
[root@VM-0-17-centos ~]# expr 1+2 1+2 [root@VM-0-17-centos ~]# expr 1 + 2 3
$(()):
echo $(($a+$b))
- 不同于expr,中间可以不需要空格
- 如果单独使用
$(($a + $b))
会报错:[root@VM-0-17-centos ~]# $(($a+$b)) -bash: 2: command not found [root@VM-0-17-centos ~]# echo $(($a+$b)) 2
$[]:
echo $[$a+$b]
,和$(())
类似let:
let sum 2+3
,用于变量赋值,一般用于for循环中如let i++
(会自动设置i
的初值为0)[root@VM-0-17-centos ~]# let sum=2+3 [root@VM-0-17-centos ~]# echo $sum 5 [root@VM-0-17-centos ~]# let sum=2 + 3 # 报错,表达式之间不能有空格 -bash: let: +: syntax error: operand expected (error token is "+") [root@VM-0-17-centos ~]# let 2+3 # 没输出 [root@VM-0-17-centos ~]#
tips:
- shell编程中的
;
表示执行完前面的命令再去执行后续命令
4.小数运算
shell编程直接进行如
2/5
的运算只会保留整数部分,为了结果更加精确,需要使用到交互运算器bc
使用方式:
- 管道:
echo "scale=2;2/6" | bc
,scale=2
表示保留小数点后两位(该方式不会进入到交互式界面)- 交互式:输入
bc
进入交互式shell[root@VM-0-17-centos ~]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. scale=2 2/4 .50
5.环境变量
- 自定义变量只在当前shell有效,要让声明的变量在子shell也能使用需要将变量声明为环境变量
- 声明环境变量方式:
- 方法1:
export back_dir=/home/backup
- 方式2:
export back_dir
(已经定义好了back_dir变量)tips:
上述方式声明的环境变量只能在当前shell和子shell生效,要想让用户登陆后该变量一直生效:
- 将变量放到
~/.bash_profile
(当前用户登录后一直有效):# .bash_profile文件内容 PATH=$PATH:$HOME/bin export PATH export a=111
- 将变量放到
/etc/profile
(所有用户登录后一直有效)
6.位置变量和预定义变量
- 之前说到变量名不能使用数字开头命名,但是在shell编程中位置变量可以使用
$1-$9
(已经预定义好了),这些变量称为位置变量:# test.sh内容 ping -c 1 $1 &> /dev/null $$ echo "$1" up || echo "$1" down # 使用位置变量(数字分配以参数的顺序为准) [root@VM-0-17-centos ~]# bash test.sh 0.0.0.0 0.0.0.0 down
- 位置变量中没有
$0
,这是因为该变量保存的当前文件名,这就是预定义变量(位置变量也是预定义变量)# test.sh内容 echo $0 [root@VM-0-17-centos ~]# bash test.sh test.sh # test.sh内容 echo $# # $#表示当前脚本使用的参数个数 [root@VM-0-17-centos ~]# bash test.sh 0 [root@VM-0-17-centos ~]# bash test.sh 11 1 # test.sh内容 echo $* # $*表示当前脚本使用的参数 [root@VM-0-17-centos ~]# bash test.sh 11 12 11 12 # test.sh内容 echo $$ # $$表示当前程序的PID [root@VM-0-17-centos ~]# bash test.sh 19888
tips:
- 文件重命名使用
mv orgfile targetfile