1 2 3 4
| // test.sh #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。 #!/bin/bash echo "hello world"
|
1 2 3 4 5 6 7
| 运行Shell脚本的方法 1 作为可执行程序 chmod +x ./test.sh #使脚本具有执行权限 ./test.sh #执行脚本 2 作为解释器参数 /bin/sh test.sh
|
Shell变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #定义变量 my_name="foo"
#使用变量 只需要在变量名前加上 $ 符号 echo $my_name #加花括号视为了帮助解释器识别变量的边界 echo ${my_name}
for skill in Java Coffee; do echo "I am good at ${skill}Script" done
#使用readonly将变量设为只读变量 my_name="foo" readonly my_name #如果尝试修改变量值,会报错 my_name="bar" #my_name: readonly variable
#删除变量 #变量被删除后不能再次使用。unset 命令不能删除只读变量。 unset my_name echo my_name #将没有任何输出
|
shell变量类型 三种
- 局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
- 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
shell字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| your_name="foo" # 使用双引号拼接 greeting="hello, "$your_name" !" greeting_1="hello, ${your_name} !" echo $greeting $greeting_1 # 使用单引号拼接 greeting_2='hello, '$your_name' !' greeting_3='hello, ${your_name} !' echo $greeting_2 $greeting_3
输出 hello, foo ! hello, foo ! hello, foo ! hello, ${your_name} !
#获取字符串的长度 str="abcd" echo ${#str} #输出 4
#提取子串 #以下实例从字符串第 2 个字符开始截取 4 个字符 str="hello world" echo ${str:1:4} $输出 ello
#查找子字符串的位置 #查找字符 l 或 o 的位置(哪个字母先出现就计算哪个): string="hello world" echo `expr index "$string" lo` # 输出 2
|
shell 数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #数组 数组名=(值1 值2 ... 值n) arr=( v1 v2 v3 ) echo "数组 ${arr[1]}" #使用 @ 符号可以获取数组中的所有元素 echo “数组中的所有元素 ${arr[@]}” #获取数组的长度 echo "数组的长度 ${#arr[@]}" #或者 echo "数组的长度 ${#arr[*]}" #获取数组单个元素的长度 echo "数组第二个元素的长度 ${#arr[1]}"
#还可以单独定义数组的各个分量:
array_name[0]=value0 array_name[1]=value1 array_name[n]=valuen
|
shell传递参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| # $ ./test.sh 1 222 3 4
#!/bin/bash echo "shell 传递参数实例" echo "执行的文件名 $0" echo "第一个参数 $1" echo "第二个参数 $2" echo "第三个参数 $3" echo "参数个数 $#" echo "所有参数 $*" echo "所有参数 加引号 \"$@\"" echo "脚本当前进程ID $$" echo "后台运行的最后一个进程的ID $!" echo "shell使用的当前选项 $-"
echo "-- \$* 演示--" for i in "$*"; do echo $i done
echo "-- \$@ 演示--" for i in "$@"; do echo $i done
#输出 shell 传递参数实例 执行的文件名 ./test.sh 第一个参数 1 第二个参数 222 第三个参数 3 参数个数 4 所有参数 1 222 3 4 所有参数 加引号 "1 222 3 4" 脚本当前进程ID 20530 后台运行的最后一个进程的ID shell使用的当前选项 hB -- $* 演示-- 1 222 3 4 -- $@ 演示-- 1 222 3 4
|
shell算数运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #!/bin/bash
a=10 b=20 echo "a $a, b $b"
#加法 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 $a % $b` echo "a % b: $val"
if [ $a == $b ] then echo "a 等于 b" fi
if [ $a != $b ] then echo "a 不等于 b" fi
#输出 a 10, b 20 a + b: 30 a * b: 200 b / a: 2 a % b: 10 a 不等于 b
#扩展 三种加法运算写法 a=10 b=20
c=`expr $a + $b`
echo "c: $c"
d=$[ `expr $a + $b` ] echo "d: $d"
e=$[ 10 + 20 ] echo "e: $e"
|
shell 关系运算符
假设变量a=10 b=20
运算符 |
说明 |
用法示例 |
-eq |
检测两个数是否相等 |
[ $a -eq $b ] 返回 false |
-nq |
检测两个数是否不相等 |
[ $a -nq $b] |
-gt |
> |
|
-lg |
< |
|
-ge |
>= |
|
-le |
<= |
|
布尔运算符
运算符 |
说明 |
用法 |
! |
非运算 |
[ !false ] 返回true |
-o |
或运算 |
[ $a -lt 20 -o $b -gt 100] |
-a |
与运算 |
|
逻辑运算符
运算符 |
说明 |
用法 |
&& |
逻辑AND |
[[ $a -lt 100 && $b -gt 100 ]] |
` |
|
` |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/bin/bash
a=10 b=20
if [[ $a -lt 100 && $b -gt 100 ]] then echo "true" else echo "false" fi
if [[ $a -lt 100 || $b -gt 100 ]] then echo "true" else echo "false" fi
|
字符串运算符
假设变量a=”abc” b=”efg”
运算符 |
说明 |
举例 |
= |
检测两个字符串是否相等 |
[ $a =$b ]返回false |
!= |
|
|
-z |
检测字符串长度是否为0,为0返回true |
[ -z $a ] false |
-n |
检测字符串长度是否不为0 |
[ -n “$a” ] true |
str |
检测字符串是否为空,不为空返回true |
[ $a ] true |
1 2 3 4 5
| tips
使用 [[ ... ]] 条件判断结构,而不是 [ ... ],能够防止脚本中的许多逻辑错误。 比如,&&、||、< 和 > 操作符能够正常存在于 [[ ]] 条件判断结构中,但是如果出现在 [ ] 结构中的话,会报错。
|
printf输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| printf 命令模仿 C 程序库(library)里的 printf() 程序。
printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
printf 命令的语法:
printf format-string [arguments...] 参数说明:
format-string: 为格式控制字符串 arguments: 为参数列表。
#!/bin/bash
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
# format-string为双引号 printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样 printf '%d %s\n' 1 "abc"
# 没有引号也可以输出 printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用 printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替 printf "%s and %d \n"
#输出 姓名 性别 体重kg 郭靖 男 66.12 杨过 男 48.65 郭芙 女 47.99 1 abc 1 abc abcdefabcdefabc def a b c d e f g h i j and 0
|
shell流程控制
if 条件
1 2 3 4 5 6 7 8 9 10
| #!/bin/bash
a=10 b=20
if test $a -lt $b; then printf '%s\n' "a < b" elif [[ $a -gt $b ]]; then echo "a > b" fi
|
for 循环
1 2 3 4 5 6 7 8 9 10
| for a in 1 2 3 4 5; do echo $a #不要忘了变量前加 $ done
#第二种写法,类似于C语言写法
#!/bin/bash for((i=1;i<=5;i++));do echo "这是第 $i 次调用" done;
|
while 语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| while condition do command done
#!/bin/bash
i=1 while(( $i<5 )) do echo $i i=`expr $i + 1` done
|
until 语句
1 2 3 4 5 6 7 8 9
| #!/bin/bash
a=0
until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` done
|
case 语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| case的语法和C family语言差别很大 它需要一个esac(就是case反过来)作为结束标记 每个case分支用右圆括号,用两个分号表示break。
#!/bin/bash echo '输入 1 到 4 之间的数字:' echo '你输入的数字为:' read aNum case $aNum in #变量后面必须跟上 in 1) echo '你选择了 1' #每一个模式必须以右括号结束 ;; #相当于break; 2) echo '你选择了 2' ;; 3) echo '你选择了 3' ;; 4) echo '你选择了 4' ;; # * 相当于 default *) echo '你没有输入 1 到 4 之间的数字' ;; esac #结束case
|
跳出循环
函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #!/bin/bash #定义函数 demoFun(){ echo "第一个shell函数" }
#执行函数 demoFun
###带返回值的函数 funcWithReturn () { echo "输入a" read a echo "输入b" read b
echo -e "a + b = \c" return $(($a + $b)) } #执行函数 funcWithReturn #通过 $?获取函数执行后的返回值 echo "$?"
###给函数传参 funWithParam () { echo $@ echo "参数总数有 $# 个!" echo "作为一个字符串输出所有参数 $* !" i=1 for arg in $@; do echo "第${i}个参数为 $arg" i=$(($i+1)) done }
funWithParam 1 2 3 4 5
|