shell
脚本运行
脚本的执行
格式: bash 脚本.sh 或 sh 脚本.sh 。
- [root@node01 ~]# ls -l
- total 4
- -rw-r--r-- 1 root root 33 May 29 11:57 hello.sh
- [root@node01 ~]# bash hello.sh
- Hello World!
- [root@node01 ~]# sh hello.sh
- Hello World!
格式: source 脚本.sh 或 . 脚本.sh
- [root@node01 ~]# ls -l
- total 4
- -rw-r--r-- 1 root root 33 May 29 11:57 hello.sh
- [root@node01 ~]# . hello.sh
- Hello World!
- [root@node01 ~]# source hello.sh
- Hello World!
绝对路径 脚本.sh (必须给执行权限)
区别 :
bash 或 sh 执行脚本时会新开一个 bash,不同 bash 中的变量无法共享。而 source 或 . 是在同一个 bash 里面执行的,所以变量可以共 享。
shell基础
注释
单行注释
要在 bash 中编写单行注释,必须在注释的开头使用井号 # 。
- #!/bin/bash
- # 我是注释
多行注释
有两种方法可以在 bash 脚本中插入多行注释:
通过在 << COMMENT 和 COMMENT 之间加上注释,可以在 bash 脚本中编写多行注释。
- #!/bin/bash
- << EOF
- 我是注释
- 我是注释
- 我是注释
- EOF
- echo "Hello World!"
- #!/bin/bash
- : ' #有空格
- 我是注释
- 我是注释
- 我是注释
- '
- echo "Hello World"
变量
Shell 声明变量的语法格式如下:
- variable=value
- variable='value'
- variable="value"
Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:
- variable=`command`
- variable=$(command)
引号
#!/bin/bash
- name="zhangsan"
- echo 'My name is ${name}'
- echo "My name is ${name}"
运行结果
- My name is ${name}
- My name is zhangsan
位置参数
运行 Shell 脚本文件时我们还可以给它传递一些参数,这些参数在脚本文件内部可以使用 $n
的形式来接收。例如, $1 表示第一个参 数, $2 表示第二个参数,依次类推。
注意:如果参数个数太多,达到或者超过了 10 个,那么就得用 ${n} 的形式来接收了,例如 ${10} 、 ${23} 。 {} 的作用是为了帮助解释器识别参数的边界,这跟使用变量时加 {} 是一样的效果。
· 范例 test.sh:
- #!/bin/bash
- echo "name: $1"
- echo "age: $2"
运行 test.sh,并附带参数:
- [root@node01 ~]# bash test.sh zhangsan 18
- name: zhangsan
- age: 18
特殊变量
字符串
定义
字符串可以由" "包含,也可以由' '包含
- 由单引号包围的字符串都会原样输出,即使是变量也无效。
- 单引号包围的字符串中不能出现 ' ,即使对单引号转义(\')也不行。
- 如果双引号中包含了变量,他会解析以后输出。
- 双引号包含的字符串中可以出现双引号,只要他被转义(\")就行。
- 不被引号包围的字符串出现变量时,他会解析。例如:
- 字符串中不能出现空格,否则会把空格后面的当成另一个字符串,例如:echo "a b c"
长度
在 Shell 中获取字符串长度很简单,具体方法如下:
- [root@node01 ~]# name=mrhelloworld
- [root@node01 ~]# echo ${#name}
- 12
拼接
案例
- #!/bin/bash
- name="zhangsan"
- age=18
- str1=$name$age # 中间不能有空格
- str2="$name $age" # 如果被双引号包围,那么中间可以有空格
- str3=$name": "$age # 中间可以出现别的字符串
- str4="$name: $age" # 这样写也可以
- str5="${name}同学: ${age}岁" # 这个时候需要给变量名加上大括号
- echo $str1
- echo $str2
- echo $str3
- echo $str4
- echo $str5
运行结果
- [root@node01 ~]# bash test.sh
- zhangsan18
- zhangsan 18
- zhangsan: 18
- zhangsan: 18
- zhangsan同学: 18岁
截取
如果想从字符串的左边开始计数,那么截取字符串的具体格式如下
- ${string:start:length}
范例:
- [root@node01 ~]# name=mrhelloworld
- [root@node01 ~]# echo ${name:2}
- helloworld
- [root@node01 ~]# echo ${name:2:5}
- hello
如果想从字符串的右边开始计数,那么截取字符串的具体格式如下
- ${string:0-start:length}
范例:
- [root@node01 ~]# name=mrhelloworld
- [root@node01 ~]# echo ${name:0-5}
- world
- [root@node01 ~]# echo ${name:0-10}
- helloworld
- [root@node01 ~]# echo ${name:0-10:5}
- hello
总结
数组
定义
- arr=(20 56 "mrhelloworld")
获取
获取数组元素的值,一般使用下面的格式:
- ${array_name[index]}
其中,array_name 是数组名,index 是下标。例如:
- [root@node01 ~]# echo ${arr[2]}
- mrhelloworld
使用 @ 或 * 可以获取数组中的所有元素,例如:
- [root@node01 ~]# echo ${arr[*]}
- 20 56 mrhelloworld
- [root@node01 ~]# echo ${ages[@]}
- 24 19 12
长度
- [root@node01 ~]# echo ${#arr[@]}
- 3
- [root@node01 ~]# echo ${#ages[*]}
- 3
如果某个元素是字符串,还可以通过指定下标的方式获得该元素的长度,如下所示:
- [root@node01 ~]# echo ${#arr[2]}
- 12
拼接
拼接数组的思路是:先利用 @ 或 * ,将数组展开成列表,然后再合并到一起。具体格式如下:
- array_new=(${array1[@]} ${array2[@]})
- array_new=(${array1[*]} ${array2[*]})
两种方式是等价的,选择其一即可。其中,array1 和 array2 是需要拼接的数组,array_new 是
拼接后形成的新数组。
案例
- #!/bin/bash
- array1=(23 56)
- array2=(99 "mrhelloworld")
- array_new=(${array1[@]} ${array2[*]})
- echo ${array_new[@]} # 也可以写作 ${array_new[*]}
运行结果如下
- [root@node01 ~]# bash test.sh
- 23 56 99 mrhelloworld
删除
在 Shell 中,使用 unset 关键字来删除数组元素,具体格式如下:
- unset array_name[index]
- #!/bin/bash
- arr=(23 56 99 "mrhelloworld")
- unset arr[1]
- echo ${arr[@]}
- unset arr
- echo ${arr[*]}
- echo '--------------------'
运行结果如下
- [root@node01 ~]# bash test.sh
- 23 99 mrhelloworld
- --------------------
shell高级
shell运算符
算数运算符
但是,Shell 和其它编程语言不同,Shell 不能直接进行算数运算,必须使用数学计算命令,
这让初学者感觉很困惑,也让有经验的程序 员感觉很奇葩。expr 是一款表达式计算工具,使用它
能完成表达式的求值操作。
- #!/bin/bash
- a=10
- b=20
- val=$(expr $a + $b)
- echo "a + b : $val"
- val=`expr $a - $b`
- echo "a - b : $val"
- val=`expr $a \* $b`
- echo "a * b : $val"
- val=`expr $b / $a`
- echo "b / a : $val"
- val=`expr $b % $a`
- echo "b % a : $val"
- if [ $a == $b ]
- then
- echo "a 等于 b"
- fi
- if [ $a != $b ]
- then
- echo "a 不等于 b"
- fi
关系运算符
运算符 | 说明 | 举例 |
-eq | 判断两个值是否相等,相等返回true | [$a -eq $b] 返回false |
-ne | 判断两个值是否不相等,不相等返回true | [$a -ne -$b]返回true |
-gt | 大于,大于返回true | [$a -gt $b]返回false |
-lt | 小于,小于返回true | [$a -lt $b]返回true |
-ge | 大于等于,返回true | [$a -ge $b]返回false |
-le | 小于等于,返回true | [$a -le $b]返回true |
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
- #!/bin/bash
- a=10
- b=20
- if [ $a -eq $b ]
- then
- echo "$a -eq $b : a 等于 b"
- else
- echo "$a -eq $b: a 不等于 b"
- fi
- if [ $a -ne $b ]
- then
- echo "$a -ne $b: a 不等于 b"
- else
- echo "$a -ne $b : a 等于 b"
- fi
- if [ $a -gt $b ]
- then
- echo "$a -gt $b: a 大于 b"
- else
- echo "$a -gt $b: a 不大于 b"
- fi
- if [ $a -lt $b ]
- then
- echo "$a -lt $b: a 小于 b"
- else
- echo "$a -lt $b: a 不小于 b"
- fi
- if [ $a -ge $b ]
- then
- echo "$a -ge $b: a 大于或等于 b"
- else
- echo "$a -ge $b: a 小于 b"
- fi
- if [ $a -le $b ]
- then
- echo "$a -le $b: a 小于或等于 b"
- else
- echo "$a -le $b: a 大于 b"
- fi
逻辑运算符
① !, "非"运算符,表达式为true,则返回false,否则返回true。
- #!/bin/bash
- a=10
- b=20
- if [ $a != $b ]
- then
- echo "$a != $b : a 不等于 b"
- else
- echo "$a == $b: a 等于 b"
- fi
② -o ,"或"运算符,有一个条件为true,则返回true
- if [ $a -lt 100 -o $b -gt 100 ]
- then
- echo "$a 小于 100 或 $b 大于 100 : 返回 true"
- else
- echo "$a 小于 100 或 $b 大于 100 : 返回 false"
- fi
③-a ,"与"运算符,两个条件都满足才返回true
- if [ $a -lt 100 -a $b -gt 15 ]
- then
- echo "$a 小于 100 且 $b 大于 15 : 返回 true"
- else
- echo "$a 小于 100 且 $b 大于 15 : 返回 false"
- fi
字符串运算符
- #!/bin/bash
- a="abc"
- b="efg"
# "=" 相等
- if [ $a = $b ]
- then
- echo "$a = $b : a 等于 b"
- else
- echo "$a = $b: a 不等于 b"
- fi
#"!=" 不等
- if [ $a != $b ]
- then
- echo "$a != $b : a 不等于 b"
- else
- echo "$a != $b: a 等于 b"
- fi
#"z" 字符串长度为0
- if [ -z $a ]
- then
- echo "-z $a : 字符串长度为 0"
- else
- echo "-z $a : 字符串长度不为 0"
- fi
#"-n" 字符串长度不为0
- if [ -n "$a" ]
- then
- echo "-n $a : 字符串长度不为 0"
- else
- echo "-n $a : 字符串长度为 0"
- fi
文件测试运算符
test命令
shell流程控制
if
- #!/bin/bash
- a=10
- b=20
- #这个案例看着有点像java中的switch语句
- if [ $a == $b ]
- then
- echo "a 等于 b"
- elif [ $a -gt $b ]
- then
- echo "a 大于 b"
- elif [ $a -lt $b ]
- then
- echo "a 小于 b"
- else
- echo "没有符合的条件"
- fi
- 当从其他格式的系统传过来文件时,要查看状态(格式)
- set ff 检查格式 fileformat=
- 然后再把格式改为对应系统的格式
- windows 为dos
- linux 为nginx
case
case 语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
- #!/bin/bash
- echo '输入 1 到 4 之间的数字:'
- echo '你输入的数字为:'
- read num
- case $num in
- 1)
- echo '你选择了 1'
- ;;
- 2)
- echo '你选择了 2'
- ;;
- 3)
- echo '你选择了 3'
- ;;
- 4)
- echo '你选择了 4'
- ;;
- *)
- echo '你没有输入 1 到 4 之间的数字'
- ;;
- esac
for
- #!/bin/bash
- for loop in 1 2 3 4 5
- do
- echo "The value is: $loop"
- done
- # 反例
- for str in 'This is a string','hello moto' #不能有逗号,系统会把逗号认作字符串
- do
- echo $str
- done
- for i in node01 node02 node03
- do
- echo $i
- done
while
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。
- # Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
- #!/bin/bash
- i=1
- while(( $i<=5 ))
- do
- echo $i
- let "i++"
- done
break
break 命令允许跳出所有循环(终止执行后面的所有循环)。
- #!/bin/bash
- while :
- do
- echo -n "输入 1 到 5 之间的数字:"
- read aNum
- case $aNum in
- 1|2|3|4|5)
- echo "你输入的数字为 $aNum!"
- ;;
- *)
- echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
- break
- ;;
- esac
- done
continue
continue 命令不会跳出所有循环,仅仅跳出当前循环。
- #!/bin/bash
- while :
- do
- echo -n "输入 1 到 5 之间的数字: "
- read aNum
- case $aNum in
- 1|2|3|4|5)
- echo "你输入的数字为 $aNum!"
- ;;
- *)
- echo "你输入的数字不是 1 到 5 之间的!"
- continue
- echo "游戏结束"
- ;;
- esac
- done
shell函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
- #!/bin/bash
- ## 第一个函数------------------------------
- demoFun(){
- echo "这是我的第一个 shell 函数!"
- }
- echo "-----函数开始执行-----"
- demoFun
- echo "-----函数执行完毕-----"
- ## 函数返回值------------------------------
- funWithReturn(){
- echo "这个函数会对输入的两个数字进行相加运算..."
- echo "输入第一个数字: "
- read aNum
- echo "输入第二个数字: "
- read anotherNum
- echo "两个数字分别为 $aNum 和 $anotherNum !"
- return $(($aNum+$anotherNum))
- }
- funWithReturn
- # 函数返回值在调用该函数后通过 $? 来获得。
- echo "输入的两个数字之和为 $? !"
- ## 函数参数------------------------------
- funWithParam(){
- echo "第一个参数为 $1 !"
- echo "第二个参数为 $2 !"
- echo "第十个参数为 $10 !" # 错误写法,如果参数个数太多,达到或者超过了 10 个,那么就得用 ${n} 的形式来接收了
- echo "第十个参数为 ${10} !" # 正确写法
- echo "第十一个参数为 ${11} !"
- echo "参数总数有 $# 个!"
- echo "作为一个字符串输出所有参数 $* !"
- }
- funWithParam a b c d e f g h i j