Skip to content

Shell编程

Shell脚本命令的工作方式:

  1. 交互式(Interactive):用户每输入一条命令就立即执行。
  2. 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。

可以通过 echo $SHELL查看系统默认终端解释器

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

执行shell脚本有两种方式:

  1. bash example.sh
  2. ./example.sh ,这种方式需要文件有执行权限

特殊字符序列

  1. 变量扩展
    • ${var}:引用变量var的值。
    • ${var:-default}:如果var未设置或为空,则返回default
    • ${var:+value}:如果var已设置且非空,则返回value,否则不返回任何内容。
    • ${var:=value}:如果var未设置或为空,则将其设置为value,并返回value的值。
    • ${var#prefix}:从var值的开头移除最短匹配prefix的子串。
    • ${var##prefix}:从var值的开头移除最长匹配prefix的子串。
    • ${var%suffix}:从var值的结尾移除最短匹配suffix的子串。
    • ${var%%suffix}:从var值的结尾移除最长匹配suffix的子串。
  2. 转义字符
    • \:反斜杠用于转义特殊字符或使特殊字符失去特殊意义(例如\n代表换行符)。
  3. 命令替换
    • command$():将命令的输出替换为命令的结果。
  4. 重定向
    • >:重定向输出至文件(覆盖)。
    • >>:追加输出至文件。
    • <:从文件读取输入。
  5. 管道
    • |:管道,将前一个命令的标准输出作为后一个命令的标准输入。
  6. 条件测试
    • [ expression ][[ expression ]]:条件测试结构,用于执行比较和文件测试等。
  7. 流程控制
    • ;:分隔多个命令。
    • &&:逻辑与,前一个命令成功后才执行下一个命令。
    • ||:逻辑或,前一个命令失败后才执行下一个命令。
    • if...then...elif...else...fi:条件判断结构。
    • while...do...done:循环结构。
    • for...do...done:遍历循环结构。
  8. 数组
    • array=(value1 value2 ...):定义数组。
    • ${array[index]}:引用数组元素。
  9. 其他特殊字符
    • $( ):命令替换,与``类似。
    • $#:脚本参数个数。
    • $*$@:所有参数作为一个列表。
    • $?:上一条命令的退出状态码。
    • $!:后台运行的最后一个进程ID。

转义字符

bash
反斜杠(\):使反斜杠后面的一个变量变为单纯的字符。
单引号(' '):转义其中所有的变量为单纯的字符串。
双引号(" "):保留其中的变量属性,不进行转义处理。
反引号(` `):把其中的命令执行后返回结果。

变量

bash
your_name="yage"    #定义变量
echo $your_name     #使用变量
unset your_name     #删除变量

传递参数

bash
echo "执行的文件名:$0";    #$0为文件名
echo "第一个参数为:$1";    #$1为传递的第一个参数
echo "第二个参数为:$2";    #$2为传递的第一个参数
ping -c 4 qq.com
echo "返回结果0为真,非0为假:$?";    #$? 的值来判断上一个命令是否执行成功
执行示例:$ ./test.sh 1 2
read -p "输入传入的参数:" num       #用户输入的参数传递给num
echo $num

判断参数

bash
#文件测试语句
	-d 测试文件是否为目录类型
	-e 测试文件是否存在
	-f 判断是否为一般文件
	-r 测试当前用户是否有权限读取
	-w 测试当前用户是否有权限写入
	-x 测试当前用户是否有权限执行
#逻辑测试语句
    && 是逻辑“与”,只有当前面的语句执行成功的时候才会执行后面的语句。
    || 是逻辑“或”,只有当前面的语句执行失败的时候才会执行后面的语句。
    ! 是逻辑“非”,代表对逻辑测试结果取反值;之前若为正确则变成错误,若为错误则变成正确。
#整数值比较语句
    -eq	是否等于
    -ne	是否不等于
    -gt	是否大于
    -lt	是否小于
    -le	是否等于或小于
    -ge	是否大于或等于
#字符串比较语句
	=	比较字符串内容是否相同
	!=	比较字符串内容是否不同
	-z	判断字符串内容是否为空

例:
[ -e /dev/cdwwrom ] && echo "Exist" || echo "No Exist"
[ ! $USER = root ] && echo "user" || echo "root"
[ 10 -eq 10 ] && echo $?

数组

bash
my_array=(A B "C" D)
echo "第一个元素为: ${my_array[0]}"   #获取数组第一个元素
echo "第二个元素为: ${my_array[1]}"
echo "数组的元素为: ${my_array[*]}"   #使用@ 或 * 可以获取数组中的所有元素
echo "数组的元素为: ${my_array[@]}"
echo "数组元素个数为: ${#my_array[*]}" #获取数组元素的个数
my_array[0]=H     #修改元素的值
unset my_array[0] #删除元素

基本运算符

bash
val=`expr 2 + 2`    #不是单引号,是esc下面那个键,数值和符号之间需要空格
num=`expr 2 /* 2`   #*号前面要加转义符\
echo "两数之和为 : $val" "两数之乘为 : $num"
a=1 b=1 
echo $[++a] $[b++]  #++放前面会先加1在返回赋值,++放后面会先赋值再加1
bash
#let 命令变量计算中不需要加上 $ 来表示变量
let a=5+4
let b=9-3 
let a+=10;let b-=10  #自加自减
echo $a $b

echo

bash
echo -e "hello\nworld"   #-e 开启转义,\n换行
echo -e "hello \c"       #\c 不换行
echo "world"
echo `date`              #显示命令执行结果,使用的是反引号

printf

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

bash
printf "Hello, world\n"
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位小数。

控制语句

bash
#if else
if [ $1 -ge $2 ]
then
        printf "大于\n"
else
        echo "小于"
fi
#写成一行
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
bash
#if else-if else
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
bash
#for循环
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done
bash
#while循环
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
bash
#until 循环
#until 循环执行一系列命令直至条件为 true 时停止,与 while 循环刚好相反
a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done
bash
#case ... esac
read -p '输入 1 到 3 之间的数字:' Num
case $aNum in
    1)  echo '你选择了 1' ;;   #;;表示break,即执行结束 
    2)  echo '你选择了 2' ;;
    3)  echo '你选择了 3' ;;
    *)  echo '你没有输入linu 1 到 3 之间的数字' ;;
esac

定义函数

bash
function test()   #定义一个函数
{
}
test    #调用函数