美文网首页
Linux shell编程

Linux shell编程

作者: 宏势 | 来源:发表于2022-04-02 15:38 被阅读0次

什么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 代替 > 比较,条件表达式[] 及运算符前后要有空格,变量赋值等号前后不能空格,分号的作用跟换行是一样的

相关文章

网友评论

      本文标题:Linux shell编程

      本文链接:https://www.haomeiwen.com/subject/hywzdrtx.html