快捷目录
- 1、解释器
- 2、shell脚本调用方式
- 3、变量
- 自定义变量
- 环境变量
- 特殊变量
- 变量的默认值
- declare 命令
- readonly命令
- let命令
- 4、数据类型
- 字符串
- 5、字符串操作
- 6、数组
- 定义数组
- 读取数组
- 修改数组
- 删除数组
- 获取数组长度
- 7、运算符
- 算术运算符
- 关系运算符
- 布尔运算符
- 逻辑运算符 要在[[ ]]中
- 字符串运算
- 文件测试运算符
- 8、流程控制
- if语句
- case语句
- for循环语句
- while循环
- util 循环
- select in循环 可以与用户进行交互
- 跳出循环 continue与break
- 9、函数
1、解释器
类型
- Bourne Again Shell(/bin/bash)
- Bourne Again Shell (/usr/bin/sh 或者 /bin/sh)
- C Shell (/usr/bin/csh)
- K Shell (/usr/bin/ksh)
- Shell for Root(/sbin/sh)
2、shell脚本调用方式
创建脚本:vim 脚本名.sh
脚本调用方式:
1、可以使用路径的方式,前提是需要有执行权限,如果没有权限使用
chmod a+x 路径/脚本名.sh ,赋予执行权限。
- 绝对路径的方式:/home/sh/1.sh
- 相对路径的方式:./1.sh
2、也可以使用sh或者bash命令调用,用这个方式,脚本没有执行权限也可以使用
- sh 1.sh 如果使用 sh /home/sh/1.sh 即sh 绝对路径,即使脚本中有错误也会往下执行完
- bash 1.sh
3、其他方式
- source 1.sh
- . 1.sh(点号+空格+脚本名)
3、变量
shell是弱类型编程语言(python,js),强类型语言(c,java,pl/sql);弱类型编程语言,声明变量,不需要指明变量的类型,shell中所有的变量默认是字符串类型;
自定义变量
命名变量
命名规则:字母、数字、下划线字符组合,第一个字符不能是数字,不许出现空格和标点符号。
赋值符号等号左右两侧不能有空格,如果有要加在双引号中
错误例子: a= www,b =1234,c=hello world
正确例子:a=www,b=1234,c=“hello world”,c=‘hello world’;
d="\t\ta string\n" # 变量值可以使用转义字符
e=$(ls -l foo.txt) # 变量值可以是命令的执行结果
f=$((5 * 7)) # 变量值可以是数学运算的结果
使用变量
$变量名
建议使用:${变量名} ,中括号括起来是一个整体。如果使用的$字符需要\转义。
abc=123
a=1
echo ${abc}
只读变量——readonly
readyonly abc #只读变量的值不能被改变
删除变量
unset 变量名
变量被删除后就不能使用,unset不能删除只读变量
由于不存在的bash变量一律为空字符串,索引也可以把要删除的变量设置为空。
环境变量
env或者printenv可以打印出所有的环境变量
常见的环境变量如下
BASHPID
Bash 进程的进程ID
HOME
用户的主目录HOST
当前自主机的名称IFS
词与词之间的分割符,默认为空格LANG
字符集以及语言编码,比如zh_CN,UTF-8PATH
由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表PWD
当前工作目录RANDOM
返回一个0到32767之间的随机数UID
当前用户的ID编号USER
当前用户的用户名
环境变量一般是只读,可以视为常量,变量名都是大写。注意变量名时区分大小写的。
看单个环境变量可以使用
printenv PATH
echo $PATH
特殊变量
-
$?
:上一个名令的退出码,用来判断上一个命令是否执行成功。返回值是0,表示上一个命令执行成功;如果非0,上一个命令执行失败。 -
$$
: 当前shell的进程ID;还可以用来命令临时变量LOGFILE=/tmp/output_log.$$
-
$_
: 上一个命令的最后一个参数 -
$!
:为最近一个后台执行的异步命令进程ID -
$0
:为当前shell脚本的名称 -
$-
:为当前shell启动的参数 -
$#
:表示参数的总数 -
$@
: 全部的参数,参数之间用空格隔开;使用时加引号,并在引号中返回每个参数。如 “$@” 用"“括起来的情况,以”$1" “$2” " 3 " . . . " 3" ..." 3"..."n"的形式输出所有参数 -
$*
: 全部的参数,以一个 单字符串 显示所有向脚本传递的参数。如果用""括起来 “$*” ,以 “$1 $2 $3…$n” 的形式输出所有参数
变量的默认值
bash提供四个特殊语法,跟变量默认值有关,以保证变量不为空。
${varname:-word}
:如果varname存在且不为空,返回它的值,否则返回word。一般是为了返回一个默认值。
例如${count:-0}
表示count变量不存在时返回0${varname:=word}
:如果varname存在就不为空会返回它的值,否则会将varname的值设置为word,并返回word值。一般是为了初始化变量的默认值值。
例如count:=1
count如果不存在时,会把count设置成1,并且返回这个值${varname:+word}
:跟第一个刚好相反,如果varname变量存在并且不为空时会返回word值,否则返回空。一般用于测试变量是否存在。
例如${count:+1}
如果count存在时会返回1(true),否则返回空${varname:?msg}
: 如果varnanme存在且不为空,就返回它的值;否则输出msg信息,并中断脚本执行。如果省略msg,默认输出"parameter null or not set"。一般是为了防止变量未定义的情况。
例如${count:?"undefined"}
表示变量未定义就中断脚本执行,并抛出异常错误"undefined"
上面四种语法如果使用在脚本里,变量名的部门可以用数字1到9,表示脚本的参数
filename=${1:?"filename missing"}
1表示脚本的第一个参数。参数不存在抛出异常filename missing并中断执行
declare 命令
可以声明一些特殊类型变量,为变量设置限制,比如声明只读或者整数型变量
declare OPTION variable=value
主要参数如下
- -a 声明数组变量
- -f 输出所有函数的定义
- -F 输出所有函数名
- -i 声明整数变量
- -l 声明变量为小写字母
- -p 查看变量信息
- -r 声明只读变量
- -u 声明变量为大写字母
- -x 该变量输出为环境变量,等同于export
declare命令如果用在函数中,声明的变量只在函数内部有效,等同于local命令。
不带任何参数时,declare命令输出当前环境的所有变量,包括函数在内,等同于不带有任何参数的set命令。
readonly命令
等同于declare -r 声明只读,不能改变变量的值,不能unset变量
有三个参数
- -f:声明的变量为函数名。
- -p:打印出所有的只读变量。
- -a:声明的变量为数组。
let命令
该命令声明的变量,可以直接指向算术表达式
$ let foo=1+2
$ echo $foo
3
支持多个变量赋值,变量之间用空格隔开
$ let "v1 = 1" "v2 = v1++"
$ echo $v1,$v2
2,1
4、数据类型
字符串
""双引号,弱引用,引号内的特殊字符有意义
''单引号,强引用,引号内的特殊字符取消意义,原样输出
双引号
your_name="hongshan"sp1="hello,"$your_name"!"p2="hello,$your_name!"$sp1 $sp2#输出:hello,hongshan!hello,hongshan!
单引号
dp1='hello,'$your_name'!'dp2='hello,$your_name!'echo $dp1 $dp2#输出:hello,hongshan! hello,$your_name!
5、字符串操作
${#varname}
获取字符串的长度
echo ${#变量}
或者echo $(expr length "\${变量}")
;$()功能和反引号``一样- 截取字符串,序号从0开始
${变量:序号:截取个数}
;echo ${变量:0-3:4}
从倒数第三个开始截取,从左往右截取长度为4的字符 - echo `expr index “$a” er ` 查找字符e或者r的位置,找不到返回0,找到返回第一次出现的位置。
6、数组
定义数组
- array=(value0 value1 value2 value3)
- array1[0]=值1
array1[1]=值2
array1[15]=值3
下标号 从0开始,给第一个元素赋值
mp3s=( *.mp3 ),定义数组可以使用通配符(将当前目录的所有 MP3 文件,放进一个数组) - declare -a命令声明一个数组
$ declare -a ARRAYNAME
读取数组
echo ${array_name[n]}
n:下标号;读取单个元素 ;下标号从0开始
echo ${array_name[*]}
:读取全部元素
echo ${array_name[@]}
:读取全部元素
修改数组
array1[0]=新值 修改array1[4]=值 新增arr+=(d e f) 使用+=在数组末尾追加成员
删除数组
- 删除单个数组
可用unset 数组名[n]
n:下标号 删除元素;删除数组元素,注意序号不会往前推; - 删除整个数组
unset 数组名;也可以设置成空字符串
获取数组长度
获取数组元素个数
echo ${#array_name[@]}
或者 echo ${#array_name[*]}
获取数组单个元素长度
echo ${#array_name[n]}
n:下标号
7、运算符
算术运算符
$((运算符))
- 对整数的进行算术运算,小数点进行运算会报错。
- 可以是多个运算符,用逗号隔开;多个运算式返回最后一个运算式的结果;
- 里面会自动忽略空格
- 里面可以使用圆括号改变优先级;
- 也可以嵌套使用
$(())
。 - 里面可以加上$,也可以不加,不会报错
- 如果在里面使用字符串,不会报错,但是会当做空值处理
$(( ))支持
算术运算
+:加法
-:减法
*:乘法
/:除法(整除)
%:余数
**:指数
++:自增运算(前缀或后缀)
–:自减运算(前缀或后缀)
位运算
<<:位左移运算,把一个数字的所有位向左移动指定的位。
>>:位右移运算,把一个数字的所有位向右移动指定的位。
&:位的“与”运算,对两个数字的所有位执行一个AND操作。
|:位的“或”运算,对两个数字的所有位执行一个OR操作。
~:位的“否”运算,对一个数字的所有位取反。
!:逻辑“否”运算
^:位的异或运算(exclusive or),对两个数字的所有位执行一个异或操作。
逻辑运算
<:小于
>:大于
<=:小于或相等
>=:大于或相等
==:相等
!=:不相等
&&:逻辑与
||:逻辑或
expr1?expr2:expr3:三元条件运算符。若表达式expr1的计算结果为非零值(算术真),则执行表达式expr2,否则执行表达式expr3。
赋值运算
parameter = value:简单赋值。
parameter += value:等价于parameter = parameter + value。
parameter -= value:等价于parameter = parameter – value。
parameter *= value:等价于parameter = parameter * value。
parameter /= value:等价于parameter = parameter / value。
parameter %= value:等价于parameter = parameter % value。
parameter <<= value:等价于parameter = parameter << value。
parameter >>= value:等价于parameter = parameter >> value。
parameter &= value:等价于parameter = parameter & value。
parameter |= value:等价于parameter = parameter | value。
parameter ^= value:等价于parameter = parameter ^ value。
注意 表达式内部赋值需要放在圆括号内,不然会报错
求值运算
逗号,在$((…))内部是求值运算符,执行前后两个表达式,并返回后一个表达式的值。
$ echo $((foo = 1 + 2, 3 * 4))
12
$ echo $foo
3
$[运算符]
以前的语法,可以做整数使用,但是不建议使用- let 命令进行运算
expr 运算式
需要注意运算符两边空格问题;不支持非整数的运算
+ 加法 `expr $a + $b`- 减法 `expr $a - $b`* 乘法 `expr $a \* $b`/ 除法 `expr $a / $b`% 取余 `expr $a % $b`
- 小数计算要用外部计算器 bc
echo "$n1+$n2"|bc
echo "$n1-$n2"|bc
echo "$n1*$n2"|bc
乘积结果小数位数 取决于 n1,n2中小数位数多的那个 ;不会进行四舍五入
除法 --scale,设置保留几位小数 --不会进行四舍五入
echo "scale=2;$n1/$n2"|bc
关系运算符
-lt 小于(less than) [ $a -lt $b ]
-le 小于等于(less equal) [ $a -le $b ]
-gt 大于(greater than) [ $a -gt $b ]
-ge 大于等于(greater equal) [ $a -ge $b ]
-eq 等于(equal) [ $a -eq $b ]
-ne 不等于(not equal) [ $a -ne $b ]
布尔运算符
-a 与运算(且) [ $a -lt 10 -a $b -gt $a ]
-o 或运算(或) [ $a -lt 10 -o $b -lt 10 ]
! 非运算(非) [ ! $a -ge $b ]
逻辑运算符 要在[[ ]]中
- && 与运算
[[ $a -lt 10 && $b -gt $a ]] 或者
[ $a -lt 10 ] && [ $b -gt $a ]
- || 或运算
[[ $a -lt 10 || $b -lt 10 ]] 或者
[ $a -lt 10 ] || [ $b -gt $a ]
- ! 非运算
[[ ! $a -ge $b ]]
字符串运算
- = 检测两个字符串是否相等,相等返回true。 [ $a = $b ]
- != 检测两个字符串是否不相等,不相等返回true。 [ $a != $b ]
- -z 检测字符串长度是否为0,为0返回true。 [ -z $a ]
- -n 检测字符串长度是否不为0,不为0返回true。 [ -n $a ] --空格会认为长度为1 a=" "
- $ 检测字符串是否不为空,不为空返回true。 [ $a ] --空格会认为是空 a=“”; b=" ";
文件测试运算符
file="/home/shell.sh/1.sh"
- -d 检查文件是否是目录,如果是,返回true。 [ -d $file ]
- -f 检查文件是否为普通文件,如果是,返回true。 [ -f $file ]
- -s 检查文件是否为空,如果不为空,返回true。 [ -s $file ]
- -e 检查文件(包括目录)是否存在,如果是,返回true。 [ -e $file ]
- -r 检查文件是否可读,如果是,返回true。 [ -r $file ] --针对文件所有者进行权限判断
- -w 检查文件是否可写,如果是,返回true。 [ -w $file ] --针对文件所有者进行权限判断
- -x 检查文件是否可执行,如果是,返回true。 [ -x $file ] --针对文件所有者进行权限判断
8、流程控制
if语句
if []thenecho "这里可以嵌套"elif []thenecho "这里可以嵌套"elseecho "这里可以嵌套"fi
case语句
case $变量 in"hello")echo;;"world")echo;;*)echo;;esac
结合正则 进行数字或者字母的判断
a=6case $变量 in[0-3])echo;;[4-7])echo;;*)echo;;esac
for循环语句
((首位;末位;步长)) i+=1;i-=1;i*=1;i/=1;s=0for ((i=0;i<=100;i+=1)) ## i+=1也可以替换成i++dos=$[s+i] 或s=$((s+i))或s=`expr $s + $i`doneecho $s
$(seq 首位 步长 末位)
s=0# seq 首位 步长 末位 --首位 步长 末位 可以是变量for i in $(seq 0 1 100) dos=$[s+i] --s=$((s+i))或s=`expr $s + $i`doneecho $s
for i in {首位..末位..步长} ---此种方式 首位 步长 末位 必须是具体值 ,不可以是变量
for i in 值1 值2 值3 值4 --循环范围直接设定为具体的一个个值doecho $idone
-- $(ls /) 反引号 ``功能相当与$() --循环范围是一个linux命令结果的范围for i in `ls /` doecho $i done
while循环
满足条件,进入循环
s=0i=0while [ $i -le 100 ]dos=$((s+i))i=$((i+1)) --let i++doneecho $s
util 循环
s=0i=0until [ $i -gt 100 ]dos=$((s+i))i=$((i+1))doneecho $s
select in循环 可以与用户进行交互
echo "请选择以下的一种水果"
select i in "apple" "pear" "orange"
do
case $i in"apple")echo "你选的是苹果";;"pear")echo "你选的是梨";;*)echo "你选的是橘子";;
esacdone
跳出循环 continue与break
continue跳出单次循环
s=0i=0while [ $i -lt 100 ]doi=$[$i+1] --i=$((i+1))yu=`expr $i % 2` --yu=$((i%2))if [ $yu -gt 0 ]thencontinuefis=$[$s+$i]doneecho "1到100偶数相加等于$s"
break跳出全部循环
exit 可以直接跳出脚本
s=0i=0while [ $i -lt 100 ]doi=$[$i+1] --i=$((i+1))if [ $i -gt 10 ]thenbreakfis=$[$s+$i] --s=$((s+i))doneecho "1到10相加等于$s"
9、函数
能够实现特定功能的一段代码, 能够实现代码的复用
两种定义方式
# 第一种
fn() {# codes
}
# 第二种
function fn() {# codes
}
先定义函数,再调用函数。function fun_name(){f_a=$1f_b=$2f_c=`expr $f_a + $f_b`echo "${f_a}+${f_b}=$f_c"}fun_name 66 77read -t 10 -p "Enter your name in 10 seconds" NAMEecho "hello $NAME"
shell函数也可以拥有return返回值 ,只能返回0-255的值,若大于255,是返回 该值%256 取余 的 结果值
若要得到return返回值结果,要结合使用 echo $?;
#!/bin/bash
function sum_002()
{
a=255
b=2
let c=a+b
return $c
}
sum_002
echo $?
----细节再补充吧,真累…