脚本

#!/bin/bash
echo "Hello World !"

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

echo 命令用于向窗口输出文本。

运行 Shell 脚本有两种方法:

1、作为可执行程序

chmod +x ./test.sh  #使脚本具有执行权限
./test.sh  #执行脚本

2、作为解释器参数

/bin/sh test.sh
/bin/php test.php

变量

# 定义一个变量
your_name="tom"

# 使用变量 ,变量前面加$ ,变量内容也可以加上花括号 ,帮助解释器识别变量
echo $your_name
your_name="Jerry"
echo ${your_name}

# 只读变量 readonly 修饰的变量只读
readonly your_name

# 删除变量	unset 命令不能删除只读变量
unset variable_name

字符串

单引号

  • 字符串原样输出 ,变量无效
  • 里面不能出现单引号(转义也不行) ,可以拼接

双引号

  • 可以有变量
  • 可以有转义字符

示例:

# 获取字符串长度
string="abcd"
echo ${#string} #输出 4

# 截取字符串
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

# 查找字符串
string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4
# 注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

数组

# 定义数组

array_name=(value0 value1 value2 value3)

array_name=(
value0
value1
value2
value3
)

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

# 读取数组	${数组名[下标]}
valuen=${array_name[n]}

# 使用@符号可以获取数组中所有元素
echo ${array_name[@]}

# 获取数组长度 
echo ${#array_name[@]}

注释

# 单行注释
# #号开头解释注释 

# 多行注释
:<<EOF
注释内容...
注释内容...
EOF

# EOF也可以使用其他符号
:<<'
注释内容...
注释内容...
'

:<<!
注释内容...
注释内容...
!

Shell 传递参数

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令 (opens new window)功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash

echo "传参实例";
echo "执行文件名:$0";
echo "第一个参数:$1";
echo "参数个数:$#";
echo "进程id:$$";
echo "后台运行的最后一个进程id:$!";
echo '$* 和 $@ 的区别 ,都是引用所有参数 ,如果有多个参数1,2,3 *等价于"1 2 3" @等价于"1" "2" "3"'
echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done

编写上面的脚本 :执行

chmod +x test.sh 
./test.sh 1 2 3

运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

val=`expr 2 + 2`
echo "两数之和为 : $val"

算术运算符

下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 -10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b 把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。

**注意:**条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]


关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
-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。

布尔运算符

下表列出了常用的布尔运算符,假定变量 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。

逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

字符串运算符

下表列出了常用的字符串运算符,假定变量 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。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

文件测试运算符

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

属性检测描述如下:

操作符 说明 举例
-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。

测试一波

#!/bin/bash

a=10
echo '定义变量a=10'
b=20
echo '定义变量b=20'
c=20

echo '算术运算符'
echo "加法:a+b=`expr $a + $b`"
echo "减法:a-b=`expr $a - $b`"
echo "乘法:a*b=`expr $a \* $b`(注意*要写成\*)"
echo "除法:a/b=`expr $a / $b`"
echo "取余:a%b=`expr $a % $b`"
if [ $a == $b ]
then
echo "a==b"
fi
if [ $a != $b ]
then
echo "a!=b"
fi

# 判断执行结果
flag(){
if [ $? == 0 ]
then
echo "true"
else
echo "false"
fi
}

echo '关系运算符'
`[ $a -eq $b ]`
echo '[ $a -eq $b ]:'`flag`
`[ $a -ne $b ]`
echo '[ $a -ne $b ]:'`flag`
`[ $a -gt $b ]`
echo '[ $a -gt $b ]:'`flag`
`[ $a -lt $b ]`
echo '[ $a -lt $b ]:'`flag`
`[ $a -ge $b ]`
echo '[ $a -ge $b ]:'`flag`
`[ $a -le $b ]`
echo '[ $a -le $b ]:'`flag`

echo '布尔运算符'
`[ !false ]`
echo '[ !false ]:'`flag`
`[ $a -lt 20 -o $b -gt 100 ]`
echo '[ $a -lt 20 -o $b -gt 100 ]:'`flag`
`[ $a -lt 20 -a $b -gt 100 ]`
echo '[ $a -lt 20 -a $b -gt 100 ]:'`flag`

echo '逻辑运算符'
`[[ $a -lt 100 && $b -gt 100 ]]`
echo '[[ $a -lt 100 && $b -gt 100 ]]:'`flag`
`[[ $a -lt 100 || $b -gt 100 ]]`
echo '[[ $a -lt 100 || $b -gt 100 ]]:'`flag`

echo '字符串运算符'
`[ $a = $b ]`
echo '[ $a = $b ]:'`flag`
`[ $a != $b ]`
echo '[ $a != $b ]:'`flag`
`[ -z $a ]`
echo '[ -z $a ]:'`flag`
`[ -n "$a" ]`
echo '[ -n "$a" ]:'`flag`
`[ $a ]`
echo '[ $a ]:'`flag`

echo '文件测试运算符'
echo '----end----'

printf 命令

#!/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

%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。

%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%-4.2f 指格式化为小数,其中 .2 指保留2位小数。

printf 的转义序列

序列 说明
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\ 一个字面上的反斜杠字符
\ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符

流程控制

if

if condition
then
	command
fi

if else

if condition
then
    command
else
    command
fi

if else-if else

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

for

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

while

while condition
do
    command
done

无限循环

while :
do
    command
done

# 或者

while true
do
    command
done

until

# until 循环执行一系列命令直至条件为 true 时停止
until condition
do
    command
done

switch

casein
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

# 两个分号;;表示break
# *) 表示匹配其他值

跳出循环

break命令允许跳出所有循环(终止执行后面的所有循环)。

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

函数

[ function ] funname [()]
{
    action;
    [return int;]
}

# 定义可以带function fun(),也可以直接fun() ,不带任何参数
# 返回值可以加: return 返回 ,如果不加 ,将以最后一条命令运行结果作为返回值
# 函数返回值在调用后通过$?来获取

参数

通过$n 获取参数,如$1是获取第一个参数 ,当n>=10时 ,需要使用${n}来获取参数

参数处理 说明
$# 传递到脚本或函数的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

输入/输出重定向

命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

文件包含

. filename   # 注意点号(.)和文件名中间有一空格

# 或者

source filename