Shell 教程
新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行
示例:
#!/bin/bash
echo "Hello World !"
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序
echo 向窗口输出文本
运行:
-
作为执行程序
chmod +x ./test.sh #使脚本具有执行权限 chmod 755 test.sh #使脚本具有执行权限 ./test.sh #执行脚本 sh test.sh #执行脚本 -
作为解释器参数
/bin/sh test.sh /bin/php test.php
变量
定义变量
变量名不加 $
==变量名与等号不能有空格==
变量命名的规范:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号
your_name="qinjx"
echo $your_name
echo ${your_name}
readonly myUrl #只读
unset your_name #删除变量
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界 推荐给所有变量加上花括号
readonly 定义为只读变量,只读变量的值不能被改变 unset 变量被删除后不能再次使用。unset 命令不能删除只读变量
变量的类型
shell运行中的三种变量
- 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
- 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量
- shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
字符串
# 单引号
str='this is a string'
# 双引号
str="Hello, I know you are \"$your_name\"! \n"
# 获取字符串长度
echo ${#str} #输出
# 截取字符串
echo ${str:1:4} # 输出 ello 从字符串第 2 个字符开始截取 4 个字符
# 查找字符串
echo `expr index "$str" io` # 输出 4
单引号 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号 双引号里可以有变量 双引号里可以出现转义字符
反引号 反引号是命令替换;命令替换是指 shell可以先执行``中的命令,将输出结果暂时保存,在适当的时候输出
数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小
# 定义数组
数组名=(值1 值2 ... 值n)
arr=(1 2 3 4)
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
# 下标的范围没有限制
# 读取数组
${数组名[下标]}
${arr[0]} # 1
echo ${arr[@]}
echo ${arr[*]}
# 获取数组长度
echo ${#arr[@]}
echo ${#arr[*]}
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
使用 @ 符号可以获取数组中的所有元素
注释
以 # 开头的行就是注释,会被解释器忽略。 多行注释
传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
$0 为执行的文件名(包含文件路径)
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
| $- | 显示Shell使用的当前选项,与set命令功能相同。 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
数组(见变量-数组)
运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
#!/bin/bash
val=`expr 2 + 2`
echo "result is : $val"
执行结果为:
result is 4
两个数相加(注意使用的是反引号` 而不是单引号 ') 两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
- 完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号
算数运算符
| 运算符 | 说明 | 举例 |
|---|---|---|
| + | 加法 | `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 ]。
- 乘号(*)前边必须加反斜杠(\)才能实现乘法运算
- 在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "\"
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
...
echo命令
输出字符串
#!/bin/sh
read name
echo "$name It is a test"
echo -e "OK! \n" # -e 开启转义
echo -e "OK! \c" # -e 开启转义 \c 不换行
# 结果定向至文件
echo "It is a test" > myfile
# 原样输出字符串
echo '$name\"'
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
printf命令
流程控制
条件语句
sh 的流程控制不可为空,如果 else 分支没有语句执行,就不要写这个 else。
# if语句
if condition
then
command1
command2
...
commandN
fi
# if-else语句
if condition
then
command1
command2
...
commandN
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
for (( ; ; ))
# until循环
until condition
do
command
done
# case ... esac
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
当变量值在列表里,for 循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的 shell 命令和语句。in 列表可以包含替换、字符串和文件名。
in列表是可选的,如果不用它,for循环使用命令行的位置参数。
break命令允许跳出所有循环(终止执行后面的所有循环)。 continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
函数
#!/bin/bash
# 定义函数,一定要在使用前
add(){
echo '请输入第一个数'
read a
echo '请输入第二个数'
read b
echo "输入的树分别为:$a $b"
return $(($a+$b))
}
# 调用函数
add
# 返回结果,获取结果使用 $?
echo "相加的结果为 $?"
- 函数返回值在调用该函数后通过
$?来获得。 - 注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
结果为
第一个参数为 1 ! 第二个参数为 2 ! 第十个参数为 10 ! 第十个参数为 34 ! 第十一个参数为 73 ! 参数总数有 11 个! 作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
{10}。当n>=10时,需要使用${n}来获取参数。
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本或函数的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数 |