Shell脚本快速入门

时间:2023-03-19 阅读:736 评论:0 作者:魏勇

由于工作中会用到shell,所以通过看视频学习了shell的语法,本篇文章简单记录一下学习成果,这样可以让我在使用时能快速找到样例,进行模仿编写,也是对初学shell的一种总结。

如果想要全面了解shell,那么可以在GNU官网了解:https://www.gnu.org/software/bash/

变量

命名规则

变量由字母、数字、下划线组成
区分大小写
数字不能开头
不能使用关键字

变量赋值

变量通过等于号来赋值。等号左侧为变量名,右侧为变量的值,将右侧的值赋值给左侧的变量,等号两边不要有空格。

变量的值为整数:

a=1
b=10+5

变量的值为字符串:

c=hello
c1=hello world  # 错误写法
c2="hello world"
c3='hello world'
c4='hello, I'm Bob'  # 错误写法,单引号会出现匹配问题
c5="hello, I'm Bob"  # 双引号包裹单引号

引用变量

方式1:$变量名

方式2:${变量名},建议使用该方式引用变量

echo 变量可以打印变量的值

举例如下,(为方便举例,下文使用了前文已定义好的变量):

echo $c  # 打印变量c,终端将显示:hello
echo ${c}  # 打印变量c,终端将显示:hello
echo $cworld  # 不显示(终端只能看到一个空白行),因为没有定义变量cworld
echo ${c}world # 显示:helloworld
echo "${c}world" # 显示:helloworld
echo "{$c}world" # 显示:{hello}world
echo $d

使用变量时,时常会将变量用双引号包裹起来,这样能尽量保证不出错。例如:

a="hello world"  # 注意hello和world之间有空格
test $a = "hello world"  # test命令1,会报错:-bash: test: too many arguments
test "$a" = "hello world"  # test命令2,不会报错

test命令1会报错,因为test命令1等价于:test hello world = "hello world", 等于号左侧的hello world并没有加双引号,那么bash在解析时就会出问题,因为等于号左侧只能有1个值,而空格会让bash认为有2个值。

test命令2不会报错,它等价于:test "hello world" = "hello world",由于双引号包裹了hello world,所以bash任务等于号左侧是1个字符串,是1个值。

数组

定义数组如下:

d=( 1 2 3 )
d1=( 1 2 "3" 4 )
d2=( "This" "is" "my" "home." )  # 等价于 d1=( This is my home.)

bash shell只支持一维数组。
数组要用一对()括起来
数组中的每个元素使用空格隔开。

获取数组元素。
${d[*]}${d[@]}: 获取数组d的全部元素
${#d[*]}: 获取数组d的元素个数
${d[index]}: 获取数组d中索引为index的元素,数组元素的索引按照从左往右、计数从0开始的顺序递增。索引也可以使用负数表达倒数第几个元素。

示例如下:

# 变量$d
echo ${d[*]}  # 打印:1 2 3
echo ${d[@]}  # 打印:1 2 3
echo ${#d[*]} # 打印:3,变量d共有4个元素,等价于:${#d[@]}
echo ${d[2]}  # 打印:3,变量d中元素1、2、3的索引分别为0、1、2
echo ${d[-2]} # 打印:2,变量d中倒数第2个元素是2

# 变量$d2
echo ${d2[*]}  # 打印:This is my home.
echo ${d2[@]}  # 打印:This is my home.
echo ${#d2[*]} # 打印:4,变量d2共有4个元素, 等价于:${#d2[@]}
echo ${d2[1]}  # 打印:is,变量d2中元素This、is、my、home.的索引分别为0、1、2、3
echo ${d2[-2]} # 打印:my,变量d2中倒数第2个元素是my

test命令

test命令可以用来检测文件是否存在、判断表达式是否正确等等。完整的test命令可以在linux终端上使用man test命令查看。下面介绍一下test命令的常用用法。

test命令检测文件:

test -e /var/log/nginx.log  # -e参数表示文件是否存在
test -f /var/log/nginx.log  # -f参数表示文件是否存在,且文件是个普通文件 
test -d /var/log  # -d参数表示文件是否存在,且文件是一个目录
test -x /tmp/1.sh  # -x参数表示文件是否有x权限

test命令检测表达式是否正确,格式test <expression>;在表达式中,运算符与两侧数字要有空格才行。

test 1=2  # 错误的用法,比较运算符“=”两边必须有空格,其它比较运算符类似

test 1 = 2  # 判断1是否等于2
test 1 -eq 2  # 判断1是否等于2,=和-eq等价
test 1 > 0  # 判断1是否大于0
test 1 -gt 0  # 判断1是否大于0,>和-gt等价

还可以使用中括号来省略test命令前缀:

# 正确用法
[ 1 = 2 ]  # 判断1是否等于2, 等价于:test 1 = 2
[ 1 -eq 2 ] # 判断1是否等于2, 等价于:test 1 -eq 2

# 错误的用法
[1 = 2]  # 错误的用法1,中括号与表达式之间要有空格
[ 1 = 2]  # 错误的用法2,中括号与表达式之间要有空格

运算符

shell脚本中的运算符大致分为以下几类:用于计算的算数运算符、用于比较的关系运算符(比较运算符)等等。

算数运算符

中文含义 运算符
相加 +
相减 -
相乘 *
相除 /
取余 %
赋值 =

比较运算符

中文含义 比较运算符1 比较运算符2
是否相等 = -eq
不相等 != -ne
大于 > -gt
大于等于 -ge
小于 < -lt
小于等于 -le

逻辑运算符

中文含义 逻辑运算符
&&
||
!

其它运算符

中文含义 运算符
检测字符串长度是否为0 -z
检测字符串长度是否不为0 -n

举例:

[ -z "hello" ]  # 表达式返回假
[ -n "hello" ]  # 表达式返回真
[ -z "" ]  # 表达式返回真
[ -n "" ]  # 表达式返回假

if分支

if分支结构有常用的三种:if,if-else,if-elif-else,它们之间可以互相嵌套。

格式

if格式:

if <条件> then
  <执行语句>
fi

if-else格式:

if <条件> then
  <执行语句1>
else
  <执行语句2>
fi

if-elif-else格式:

if <条件1> then
  <执行语句1>
elif <条件2> then
  <执行语句2>
else
  <执行语句3>
fi

示例

如果年龄大于18岁则为成年人

if [ $age -ge 18 ] then
  echo "成年人"

# 等价于
if test $age -ge 18 then
  echo "成年人"

如果年龄大于等于18岁为成年人,否则为未成年人

if [ $age -ge 18 ] then
  echo "成年人"
else
  echo "未成年人"
fi

如果年龄大于等于60则为老年人,年龄在[40, 60)的为中年人,年龄在[18, 40)的为青年人,年龄在[0, 18)的为未成年人

if [ $age -ge 60 ] then
  echo "老年人"
elif [ $age -ge 40 ] then
  echo "中年人"
elif [ $age -ge 18 ] then
  echo "青年人"
else
  echo "未成年人"
fi

while循环

满足条件时,执行循环体

格式

while <条件> 
do
  <代码块>
done

示例

打印1到5,每次打印后变量+1

age=1
while [ $age -le 5 ]
do
  echo $age
  age=$(( age + 1 ))
done

# 输出示例
1
2
3
4
5

until循环

执行循环,直到满足条件时停止

格式

until <条件> 
do
  <代码块>
done

示例

打印age并自减去1,直到age小于等于0停止

age=5
until [ $age -le 0 ]
do
  echo $age
  age=$(( age - 1 ))
done

# 输出示例
5
4
3
2
1

for循环

for循环有两种格式:for-in和c风格的for

格式

for-in格式如下:

for <变量> in <值1> <值2> <值3> <值4> ...
do
  <代码块>
done

c风格的for如下:

for (( <初始变量>; <循环条件>; <变量变化> ))
do
  <代码块>
done

示例

for-in形式

for world in This is my home. 
do
  echo $world
done

# 输出结果
This
is
my
home.

c风格的for

for (( a=1; a<5; a++ ))
do
    echo $a
done

# 输出结果
1
2
3
4

结束循环

分为break和continue

break 结束整个循环

题目:打印1到5,如果遇到偶数,则不打印并且结束整个循环。

# while写法
a=1
while [ $a -le 5 ]
do
  if [ $(( a % 2 )) = 0 ]; then
    break
  fi
  echo $a
  a=$(( a + 1))
done

# for写法1
for a in 1 2 3 4 5
do
  if [ $(( a % 2 )) = 0 ]; then
    break
  fi
  echo $a
done

# for写法2
for (( a = 1; a <= 5; a++ ))
do
  if [ $(( a % 2 )) = 0 ]; then
    break
  fi
  echo $a
done

continue 结束本次循环,继续下一个循环

题目:打印1到5,如果遇到偶数,则不打印并且跳过本次循环。

# while写法
a=1
while a -le 5
do
  if [ $a % 2 = 0 ] then
    continue
  fi
  echo $a
  a=$(( a + 1))
done

shell中各种括号:()、(())、[]、[[]]、{}

参考:https://www.runoob.com/w3cnote/linux-shell-brackets-features.html

本文链接: https://django.org.cn/?id=9 转载请注明出处!

评论区 交流一下吧!

共有0条评论来说两句吧...

欢迎 发表评论: