什么shell
shell 是用户与linux通讯的桥梁,既是一种命令语言,也是一种程序设计语言。我们经常说的shell脚本就是用shell编写的程序。
Shell种类
#查看当前服务器支持shell
cat /etc/shells 或者 chsh -l
#查看当前服务器默认shell
echo $SHELL
当前大多数linux系统默认使用/bin/bash,/usr/sbin/nologin(/sbin/nologin)
- Bourne Again Shell(/bin/bash)最常用的,默认值
- Bourne Shell(/usr/bin/sh或/bin/sh)Unix最早使用的shell,已被/bin/bash取代
- C Shell(/bin/csh)被/bin/tcsh所取代
- TC Shell (/bin/tcsh) /bin/csh的增强版
- Tmux(/usr/bin/tmux) 终端复用软件
- K Shell(/bin/ksh)
运行环境
打开文本编辑器,扩展名为sh,解释执行,支持两种运行方式
- 可执行程序执行
vim /test.sh #脚本文件第一行指定解释器 #!/bin/bash echo hello world!
chmod +x tes.sh #增加可执行权限 ./test.sh #当前目录执行
- 作为解释器参数
会忽略脚本里面的第一行指定的解释器
/bin/bash test.sh
数据类型
shell脚本基础数据类型只支持数字类型和字符串,不支持布尔类型
变量
str="Linux shell编程"
num=100
echo ${str} #读取变量用$,大括号可选,主要用于识别变量的边界
echo $num
#通过命令语句赋值变量
for file in `ls /etc`
do
echo ${file}
done
#或者
for file in $(ls /etc)
do
echo ${file}
done
# 只读变量
readonly readonly_str="Linux shell 编程"
readonly_str="修改Linux shell编程" #会报错,不允许修改
unset readonly_str #会报错
#删除变量
str="Linux shell 编程"
unset str #删除变量,变量为空
str="新 Linux shell 编程" #从新声明变量
echo $str
变量复制等号前后不能有空格,使用readonly设置成只读变量,只读变量不能删除
单引号和双引号区别
-
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的,不支持转义字符;
-
单引号字串中引号成对出现,作为字符串拼接使用
-
双引号里可以有变量
-
双引号里可以出现转义字符
say='welcome'
str='Linux shell编程${say}'
str1='Linux shell编程'${say}''
str2="Linux shell编程${say}"
str3="Linux shell编程\"${say}\""
echo $str $str1
echo $str2
echo $str3
#输出结果
Linux shell编程${say}
Linux shell编程welcome
Linux shell编程welcome
Linux shell编程"welcome"
浮点型运算采用bc或者awk处理,示例如下:
result=$(echo "5.01-4*2.0"|bc)
echo $result
result=$(awk 'BEGIN{print 7.01*5-4.01 }')
echo $result
字符串
- 获取字符串长度
str="abcdefg"
echo ${#str}
- 截取字符串
str="abcdefg"
echo ${str:3} #输出defg 从i=3开始截取
echo ${str:2:3} #输出cde 从i=2开始截取3个字符
echo ${str:0-4:2} #输出de 从右边第4个字符开始,截取2个字符
- 按字符内截取
net=https://www.jianshu.com/u/86f7ba800fed
#1. #*/ 表示从左边开始,删除第一个/和左边的字符
echo ${net#*/} #/www.jianshu.com/u/86f7ba800fed
#2. ##*/ 表示从左边开始,删除最后一个/和左边的字符
echo ${net##*/} #86f7ba800fed
#3. %/* 表示从右边开始,删除第一个/和右边的字符删
echo ${net%/*} #https://www.jianshu.com/u
#4. %%/* 表示从右边开始,删除最后一个/和右边的字符删
echo ${net%%/*} #https:
具体更复杂的字符串操作可以参考awk,sed, expr,cut等命令
数组
只支持一维数组,元素之间用空格分隔,array_name=(value1 value2 ... valuen),元素可以字符串也可以数字
array=("val1" "val2" 10 11)
array[4]=12
array[10]=100
echo "数组长度为${#array[*]},${#array[@]}" #获取数组长度
#遍历数组
for val in ${array[*]} #获取数组所有元素
do
echo "数组元素值为:${val}"
done
运算符
原生bash不支持简单的数学运算,需通过(()),[],let或者expr实现, 算数运算如下:
a=10;b=20
val=`expr $a + $b` // val=$((a+b)) 或val=$[a+b] 或者let val=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
乘号(*)前边必须加反斜杠()才能实现乘法运算;运算符和中括号前后必须有空格,例如[$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
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算符 | [ ! $a -gt $b] 返回true |
-o | 或运算符 | [ $a -lt 20 -o $b -gt 100 ] 返回 true |
-a | 与运算符 | [ $a -lt 20 -a $b -gt 100 ] 返回 false |
逻辑运算符 假设变量a为10,b为20
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑AND | [[ $a -lt 20 && $b -gt 100 ]] 返回 false |
|| | 逻辑OR | [[ $a -lt 20 || $b -gt 100 ]] 返回 true |
逻辑运算符多了一个中括号[]
字符串运算符
a="abc";b="efg"
if [ $a = $b ] #判断字符串是否相等 [ $a != $b ] 判断字符串不相等
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a ] #判断字符串不为空(true)
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
if [ -z $a ] #判断字符串长度为0(true) [ -n "$a" ] 判断字符串长度不为0(true)
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
文件测试运算符
file="/var/www/test.sh"
if [ -r $file ] #判断文件是否可读, [ -w $file ] 是否可写,[ -x $file ]是否可执行
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -e $file ] #判断文件是否存在 [ -s $file ]文件是否为空
then
echo "文件存在"
else
echo "文件不存在"
fi
if [ -f $file ] #判断是否为普通文件(既不是目录,也不是设备文件) [ -d $file ]是否是目录
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
流程控制
- if else fi
a=10;b=20
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
- for 循环
for((i=0;i<10;i++))
do
echo "index:$i"
done
for var in "index1" "index2" "index3" "index4" "index5"
do
echo "$var"
done
- case ...esac
code="shell"
case "$code" in
"java") echo "最喜欢java"
;;
"shell") echo "最喜欢shell"
;;
"go") echo "最喜欢go"
;;
"*") echo "都喜欢" #匹配不到执行该语句
;;
esac
- while 语句
num=1
while(( $num<=5 ))
do
echo $num
num= `expr $num + 1` # let "int++"
done
break终止结束循环;continue指的是本次的循环,进入下一次的循环
函数
- 函数不带任何参数, 可以省略关键字function
- 调用函数可以传递任意个数参数,函数内通过$n形式获取
- 函数返回,可以显示return返回,如果不加以最后一条命令运行结果作为返回值,且只能返回整数,0表示成功,其它值表示失败,建议显示return
- 函数返回不能赋值,所以一般通过函数内赋值给全局变量来获取返回值
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
function add(){
echo "执行相加操作"
return `expr $1 + $2`
}
function reduce(){
echo "执行相减操作"
expr $1 - $2
}
add 10 20;echo $? ;echo $?
#result=add 30 50 会报错
reduce 100 20;echo $? ;echo $?
输出结果如下:
执行相加操作
30
0
执行相减操作
80
0
0
输入/输出重定向
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
echo "Linux shell编程" > test.txt
#往test.txt追加字符串
echo "Linux shell编程" >> test.txt
# 统计test.txt 的行数
wc -l < test.txt
2>&1 stdout与stderr合并,>号前后不能有空格
#stderr重定向到test.txt
echo "Linux shell编程" 2> test.txt
#stdout 和 stderr 合并后重定向到 file
echo "Linux shell编程" > test.txt 2>&1
#输出重定向到/dev/null,达到“禁止输出”效果,即结果不会输出到屏幕上
echo "Linux shell编程" > /dev/null
#同时屏蔽 stdout 和 stderr
echo "Linux shell编程" > /dev/null 2>&1
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入
创建文件并写入内容例子如下:
cat > test.txt<<EOF
欢迎学习
Linux shell编程
EOF
文件包含
文件包含主要用于提取一些公共脚本,支持两种方式:
source ./basic.sh 或者 . ./basic.sh(注意点号(.)和文件名中间有一空格)
vim basic.sh
#!/bin/bash
str="Linux shell编程"
vim test.sh
#!/bin/bash
source ./basic.sh #或者../basic.sh
echo $str
shell 语法相对比较单一,只支持数字和字符串基础类型;扩展类型只支持函数和数组,函数返回值只支持数字,不能赋值给变量;算术运算需引入expr或者awk,-gt 代替 > 比较,条件表达式[] 及运算符前后要有空格,变量赋值等号前后不能空格,分号的作用跟换行是一样的
网友评论