shell 入门
-
脚本格式
#!/bin/bash
-
第一个shell脚本
-
创建一个shell脚本,输出 hello world
-
示例
#!/bin/bash echo "hello world"
- 脚本常用的执行方式
sh test.sh bash test.sh ./test.sh source test.sh
-
系统变量
-
系统变量
$HOME # 获取家目录地址 $PWD # 获取当前的路径 $SHELL # 获取当前使用的shell解释器
自定义变量规则
- 变量名可以由字符、数字和下划线组成, 但是不能以数字开头,环境变量建议大写。
- 等号的两侧不能有
空格
- bash中默认的变量都是字符串类型,所以无法直接进行数值运算。
- 变量的值如果有空格,需要使用双引号或者单引号括起来。
-
声明变量
注意:等号的左右时没有空格的
# 声明变量 A 和 B A=1 B=2
-
获取变量
使用 $ 符号
# 获取变量 $A $B
-
声明静态变量
readonly
静态变量,只能读取,不能进行重新赋值和删除
# 声明静态变量 readonly C=1 # 读取静态变量 echo $C
特殊变量
-
${n}
n 为数字,$0 代表脚本名称,$1代表第一个参数,依此类推。
如果参数的个数超过9个,则需要加
{}
,例如 ${10}#!/bin/bash echo "$0 $1 $2 $3"
./test.py 1 2 3
-
$#
获取传入参数的个数, 一般用于循环
#!/bin/bash echo "参数的个数:"$#
./test.py 1 2 3 4 5 6 7 8
-
$*
获取命令行中的所有的参数,会把所有的参数当成一个整体
#!/bin/bash echo $*
-
$@
获取命令行中的所有的参数,但会将参数区别对待
#!/bin/bash echo $@
-
$?
最后一次执行命令的返回状态,这个变量值为0,证明上一次执行的命令是正确的,如果这个值为非0,则证明上一次执行的命令是错误的。
#!/bin/bash cat ./b.txt echo $?
运算符
-
基本语法
$((运算表达式))
或者$[运算表达式]
expr +(加法),-(减法),*(乘法),/(除法),%(取余),expr 运算符间有空格
-
示例
-
计算 3+2的值
root@win:~# expr 2 + 3 5
-
计算 3-2的值
root@win:~# expr 3 - 2 1
-
计算 (2+3)*4的值
root@win:~# expr `expr 2 + 3` * 4 20
-
使用 $ 计算, 使用
()
需要有至少两层,例如$((表达式))
root@win:~# echo $(((2+3)*4)) 20 root@win:~# echo $[2+3] 5
-
条件判断
-
基本语法
-
语法
[ condition ]
-
注意事项
- 条件前后要有空格,条件为空则为false, 否则为true
-
-
比较符号
-
=
字符串等于 -
-lt
小于 -
-gt
大于 -
-eq
等于 -
-le
小于等于 -
-ge
大于等于 -
-ne
不等于 -
示例
# 判断 23 大于等于 22 root@win:~# [ 23 -ge 22 ] root@win:~# echo $? 0 # 判断 23 大于等于 24 root@win:~# [ 23 -ge 24 ] root@win:~# echo $? 1
-
-
按照文件权限进行判断
-
-r
有读的权限 -
-w
有写的权限 -
-x
有执行的权限 -
示例
# 查看文件 qiang@win:~$ ll -rw-rw-rw- 1 qiang qiang 0 Jul 11 15:37 a.txt -rwxr-xr-x 1 root root 34 Jul 11 09:54 helloworld.sh* # 判断 helloworld.sh 是否有读的权限(有) qiang@win:~$ [ -r helloworld.sh ] qiang@win:~$ echo $? 0 # 判断 a.txt 是否有执行的权限(无) qiang@win:~$ [ -x a.txt ] qiang@win:~$ echo $? 1
-
-
按照文件类型进行判断
-
-f
文件存在,并且是一个常规的文件 -
-e
文件存在 -
-d
目录存在 -
示例
# 判断一个文件是否存在 (存在) qiang@win:~$ [ -f a.txt ] qiang@win:~$ echo $? 0 # 判断一个文件是否存在 (不存在) qiang@win:~$ [ -f b.txt ] qiang@win:~$ echo $? # 判断b.txt是一个目录 (不是) qiang@win:~$ [ -d b.txt ] qiang@win:~$ echo $? 1 # 创建目录c并且判断c 是一个目录(是) qiang@win:~$ mkdir c qiang@win:~$ [ -d c ] qiang@win:~$ echo $? 0
-
-
多条件判断
-
&&
表示前一条命令执行成功时,才执行后一条命令,如果前一条命令执行失败,则后面命令不会执行。 -
||
表示前一条命令执行成功时,就不会执行后一条命令。如果前一条命令执行失败,才会执行后一条命令 -
示例
# 判断22大于21为真,然后echo ok为真, 不执行或语句 qiang@win:~$ [ 22 -gt 21 ] && echo ok || echo success ok # 判断22大于21为假,不执行echo ok语句, 执行或语句,输出 success qiang@win:~$ [ 22 -gt 23 ] && echo ok || echo success success
-
条件分支
-
if
语句-
基本语法
# 第一种方式 if [ 条件表达式 ];then 程序 fi # 第二种方式 if [ 条件表达式 ] then 程序 fi
-
示例
#!/bin/bash if [ $1 -eq 1 ] then echo "输入的参数是1" elif [ $1 -eq 2 ] then echo "输入的参数是2" else echo "输入错误" fi
#!/bin/bash if [ $1 -eq 1 ];then echo "输入的参数是1" elif [ $1 -eq 2 ];then echo "输入的参数是2" else echo "输入的参数有误" fi
-
注意事项
- [ 条件表达式 ] ,中括号与条件表达式中间必须有空格
- 要有
fi
结尾
-
-
case
语句-
基本语法
case
-
注意事项
case
行结尾为单词in
, 每一个模式匹配符必须以)
结束。1)
里面的值最好是字符串类型。- 双分号
;;
表示命令序列结束。相当于break
*)
表示默认模式,相当于default
- 默认模式
;;
可写可不写,推荐 写
-
示例
#!/bin/bash case $1 in "1") echo "python" ;; "2") echo "java" ;; "h") echo "h" ;; *) echo "others" ;; esac
-
循环语句
-
for
循环-
基本语法
for ((初始值; 循环控制条件;步长)) do 程序 done for 变量 in 值1 值2 值3 do 程序 done
-
注意事项
for(())
要有两个括号- 程序需要在
do
和done
之间
-
示例
#!/bin/bash # 计算1到100的和 sum=0 for ((i=1;i<=100;i++)) do sum=$(($sum+$i)) done echo $sum #!/bin/bash # 获取参数并打印,$@和$*效果是一样的 for i in $@ do echo $i done for i in $* do echo $i done # 获取参数并打印,“$@”和“$*”效果是不一样的 # "$@" 和上面的是一样的,也是分别打印 # "$*" 和上面的不一样了,他是作为一个整体输出的 for i in “$@” do echo $i done for i in “$*” do echo $i done
-
-
while
循环-
基本语法
while [ 条件表达式 ] do 程序 done
-
注意事项
- 条件表达式两边需要有空格
- 程序必须在
do
和done
中间 - 程序必须有限制条件,否则会造成死循环
-
示例
#!/bin/bash # 计算1加到100的和 i=1 sum=0 while [ $i -le 100 ] do # 累加的和 sum=$[$sum+$i] # 限制条件 i=$[$i+1] done echo $sum
-
读取控制台的输入
-
read
-
基本语法
read -t 读取数据的时间 -p "提示语句" 接收数据的变量
-
注意事项
-p
指定读取值的提示符-t
指定读取时等待的时间,默认单位秒。如果超出时间,则退出程序- 需要有一个接收数据的变量
-
案例
#!/bin/bash # 20s 内输入数据,用Name来接收数据,并打印 read -t 20 -p "input your name" Name echo $Name
-
函数
-
系统函数
-
basename
功能:获取文件的名称
# 获取文件名称 qiang@win:~$ basename /home/qiang/case.sh case.sh # 获取文件名称,不带后缀 qiang@win:~$ basename /home/qiang/case.sh .sh case
-
dirname
功能: 获取文件的绝对路径
# 获取文件的绝对路径 qiang@win:~$ dirname /home/qiang/case.sh /home/qiang
-
-
自定义函数
-
基本语法
[function] funcname[()] { 程序 [return int;] } funcname
-
注意事项
- 先声明函数,然后才可以调用
- 函数的返回值,只能使用
$?
来调用,可以显示条件return int
,如果不加,则默认最后条命令执行的结果作为返回值。 return返回值的范围在0~255之间
-
示例
#!/bin/bash # 定义求和函数 function add() { sum=$[$1+$2] echo $sum } read -p "请输入第一个参数: " p1 read -p "请输入第二个参数: " p2 add $p1 $p2
-