Linux之Shell脚本编程入门

发布时间:2024年01月19日

Linux之Shell脚本编程入门

What is Shell?

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用系统操作内核。

Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。

Shell脚本编程入门

  1. 查看Linux系统已提供的shell解释器
cat /etc/shells
  1. 查看当前系统使用的默认shell解释器
echo $SHELL

1. 脚本格式

脚本一**#!/bin/bash**开头(指定解析器)

2. 第一个Shell脚本:hello World

# 1. touch hello.sh

# 2.vim hello.sh

# 3.输入下面内容
#!/bin/bash
echo "Hello World!"

#4.执行hello.sh
sh hello.sh 
#或 bash hello.sh
#或使用绝对路径:
# sh /home/myShell/hello.sh
# bash /home/myShell/hello.sh
# 5.打印结果
Hello World!

#6.使用./hello.sh 执行时提示权限不够
[root@MiWiFi-R4CM-srv myShell]# ./hello.sh
-bash: ./hello.sh: 权限不够
# 6.1 授权
chmod 777 hello.sh
# 6.2 再使用 ./ 执行hello.sh
./hello.sh 
#或使用绝对路径,如下:
/home/myShell/hello.sh 

为什么使用 sh 或bash执行shell脚本时不需要执行权限,而使用**./**执行shell脚本时需要执行权限呢?

  1. 使用sh或bash时,本质时bash解析器帮你执行脚本,所以脚本本身不需要执行权限;
  2. 使用./执行shell时,本质是脚本需要自己执行,所有需要执行权限

3.第二个 shell脚本:duo命令处理

需求:创建一个shell脚本,本脚本可以在 /home/myShell/目录下建立test.txt文件,并向test.txt文件中增加“I love shell”;

  1. 创建一个名为“appendStr.sh”的shell脚本,内容如下:
#!/bin/bash
cd /home/myShell/
touch test.txt
echo "I love shell" >> test.txt

4. shell中变量

4.1 常用系统变量

$HOME $PWD $ SHELL $USER等

echo $HOME

echo $PWD

echo $SHELL

echo $USER

4.2 自定义变量

  • 基本语法
  1. 定义变量:变量名=值【注意:= 两边不能有空格】
# 定义一个变量A,赋值为A
A=1
# 取变量的值
echo $A
  1. 撤销变量:unset 变量名
unset A 
  1. 声明一个静态变量:readonly 变量名,注意:不能unset,重启系统后失效
readonly B=2
  • 定义变量的规则
  1. 变量名可以由字母、数字和下划线组成,但不能以数字开头,环境变量名建议大写;

  2. 赋值符号(=)两边不能有空格;

  3. 在bash,中变量默认类型都是字符串类型,无法直接进行数字运算;

  4. 变量的值如果有空格,需要使用双引号或单引号括起来,如下

D="I love shell"D='I love shell'
  1. 可把变量提升为全局环境变量,可供其他Shell程序使用
export 变量名

4.3 特殊字符: $n

  1. 基本语法

$n: n为数字,$0代表该脚本名称,$1- 9 代表第一个至第九个参数,十以上的参数需要用大括号括起来,如 9代表第一个至第九个参数,十以上的参数需要用大括号括起来,如 9代表第一个至第九个参数,十以上的参数需要用大括号括起来,如{10}

  • 实操案例

  • 输出该及爱哦本文件名称,输入参数1和输入参数2的值

新建文件名为 paramaters.sh 的shell,内容如下

#!/bin/bash
echo "$0  $1  $2"

执行paramaters.sh

[root@MiWiFi-R4CM-srv myShell]# sh inputoutput.sh a b 
inputoutput.sh  a  b

4.4 特殊变量: $#

$#功能描述:获取所有输入参数的个数;如果定义了参数但为输入,则为0;常用与循环

  • 实操案例

以paramaters.sh为例

#!/bin/bash
echo "$0  $1  $2"
echo $#

# 不输入参数的情况 
[root@MiWiFi-R4CM-srv myShell]# sh paramaters.sh 
inputoutput.sh    
0
# 输入参数的情况
[root@MiWiFi-R4CM-srv myShell]# sh paramaters.sh hello "this is shell"
inputoutput.sh  hello  this is shell
2

[root@MiWiFi-R4CM-srv myShell]# sh paramaters.sh hello "this is shell" world
inputoutput.sh  hello  this is shell
3

4.5 特殊变量: ? 与 *与 ?@

KaTeX parse error: Undefined control sequence: \* at position 1: \?*?:这个变量代表命令行中所有的参…*是把所有的参数看成一个整体;

@ : 这个变量也代表命令行中所有的参数,但 @:这个变量也代表命令行中所有的参数,但 @:这个变量也代表命令行中所有的参数,但@把每个参数区分对待

  • 实操案例
#  paramaters.sh 内容如下
#!/bin/bashi-R4CM-srv myShell]# 
echo "$0 $1 $2"
echo $#
echo $*
echo $@

# 执行
[root@MiWiFi-R4CM-srv myShell]# bash paramaters.sh p1 p2 p3
paramaters.sh p1 p2
3
p1 p2 p3   # $* 输出所有参数
p1 p2 p3   # $@ 输出所有参数

4.6 特殊变量: $?

$?: 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个参数,由命令自己来决定),则证明上一个命令执行不正确

  • 实操案例:
[root@MiWiFi-R4CM-srv myShell]# sss
-bash: sss: 未找到命令
[root@MiWiFi-R4CM-srv myShell]# echo $?
127 #未正确执行

[root@MiWiFi-R4CM-srv myShell]# ./hello.sh 
Hello World!
[root@MiWiFi-R4CM-srv myShell]# echo $?
0 # 正确执行

5. 运算符

5.1 基本语法

  1. ( ( 运算式 ) ) ”或“ ((运算式))” 或 “ ((运算式))[运算式]”
  2. expr + , - , *, / , % [expr 加,减,乘,除,取余]
    • 注意:expr 与运算的数值及运算符之间要有空格

5.2 实操案例

  1. 使用 “ ( ( 运算式 ) ) ”或“ ((运算式))” 或 “ ((运算式))[运算式]” 进行计算
# 加法
[root@MiWiFi-R4CM-srv myShell]# ADD=$((2+3))
[root@MiWiFi-R4CM-srv myShell]# echo $ADD
5
# 加、除、减
[root@MiWiFi-R4CM-srv myShell]# SUB=$[(3+5)/2-2]
[root@MiWiFi-R4CM-srv myShell]# echo $SUB
2
# 混合运算
[root@MiWiFi-R4CM-srv myShell]# MULT=$[(5+5)-4*3/2%5]
[root@MiWiFi-R4CM-srv myShell]# echo $MULT
9
  1. 使用expr 计算
[root@MiWiFi-R4CM-srv myShell]# expr 4+3
4+3
# + 
[root@MiWiFi-R4CM-srv myShell]# expr 4 + 3
7
# - 
[root@MiWiFi-R4CM-srv myShell]# expr 6 - 3
3
# * 
[root@MiWiFi-R4CM-srv myShell]# expr 5 \* 3
15
# /
[root@MiWiFi-R4CM-srv myShell]# expr 6 / 3
2
[root@MiWiFi-R4CM-srv myShell]# expr 6 % 5
1
# 计算 (2 + 4) * 5 的值
# 先使用``包住括号内的运算,然后在*5,如下:
[root@MiWiFi-R4CM-srv myShell]# expr `expr 2 + 4` \* 5
30
[root@MiWiFi-R4CM-srv myShell]# 

6. 条件判断

6.1 基本语法

[condition] (注意condition前后要有空格)

注意:条件非空即为true,[yuan]返回true,[]返回false

6.2 常用判断条件

  1. 两个整数之间比较
比较符说明
=字符串比较
-lt小于(less than)
-le小于等于(less equal)
-eq等于(equal)
-gt大于(greater than)
-ge大于等于(greater than)
-ne不等于(Not equal)
  1. 按照文件权限进行判断
判断符说明
-r有读的权限(read)
-w有写的权限(write)
-x有执行权限(execute)
  1. 按照文件类型进行判断
判断符说明
-f文件存在并且是一个常规的文件(file)
-e文件存在(existence)
-d文件存在并是一个目录(directory)

6.3 实操案例

  1. 数字比较运算
# 1 > 2 ?
[root@MiWiFi-R4CM-srv myShell]# [ 1 -gt 2  ] 
[root@MiWiFi-R4CM-srv myShell]# echo $?
127

# 1 < 2 ?
[root@MiWiFi-R4CM-srv myShell]# [ 1 -lt 2  ] 
[root@MiWiFi-R4CM-srv myShell]# echo $?
0

# 3-1 = 2 ?
[root@MiWiFi-R4CM-srv myShell]# [ $((3-1)) -eq 2 ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
0
  1. 文件权限判断练习
[root@MiWiFi-R4CM-srv myShell]# ll
-rwxrwxrwx. 1 root root 32 33 13:00 hello.sh

# hello.sh 文件 是否有可写权限?
[root@MiWiFi-R4CM-srv myShell]# [ -w hello.sh ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
0 # 有
# hello.sh 文件 是否有可读权限?
[root@MiWiFi-R4CM-srv myShell]# [ -r hello.sh ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
0 # 有
# hello.sh 文件 是否有可执行权限?
[root@MiWiFi-R4CM-srv myShell]# [ -e hello.sh ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
0 # 有 
  1. 文件类型练习
# 查看 /home/myShell/test.txt 文件存在且是一个常规文件?
[root@MiWiFi-R4CM-srv myShell]# [ -f /home/myShell/test.txt ]
[root@MiWiFi-R4CM-srv myShell]# echo $?

0 # 存在
# 查看 /home/myShell/aaa.txt 文件是否存在
[root@MiWiFi-R4CM-srv myShell]# [ -e /home/myShell/aaa.txt ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
1 # 不存在

# /home/myShell 是否为一个目录
[root@MiWiFi-R4CM-srv myShell]# [ -d /home/myShell ]
[root@MiWiFi-R4CM-srv myShell]# echo $?
0 #是目录
  1. 多条判断

&& : 表示前一条命令执行成功时,才执行后一条命

|| : 表示上一条命令执行失败后,才执行下一条命令

[ condition ] && echo OK || echo NotOK

[ condition ] && [] || echo NotOK

7.流程控制

7.1 if 判断

  1. 基本语法
if [ 条件判断式 ];then
	# 程序代码
elif [ 条件判断式 ];then
	# 程序代码
fi
# 或者
if [ 条件判断式 ]
  then
  	# 程序代码
elif [ 条件判断式 ]
  then 
  	# ...
fi  	

注意:

  • [ 条件判断式 ],中括号和条件判断式之间必须有空格

  • if 后要有空格

  • 实操案例:

a. 输入一个数字,如果输入的是1、2、3,则输出具体的数字,否则什么也输出

b. 新建一个shell文件,名称为:control_if.sh ,内容如下

#!/bin/bash
if [ $1 -eq "1" ]
then
        echo "You entered the number 1"
elif [ $1 -eq "2" ]
then
        echo "You entered the number 2"
fi      
if [ $1 -eq "3" ];then
        echo "You entered the number 3"
else
        echo "You entered the other number"
fi

c. 执行control_if.sh

# 不带参数执行
[root@MiWiFi-R4CM-srv myShell]# sh controll_if.sh 
controll_if.sh: 第 2 行:[: -eq: 期待一元表达式
controll_if.sh: 第 5 行:[: -eq: 期待一元表达式
controll_if.sh: 第 9 行:[: -eq: 期待一元表达式

# 执行controll_if.sh 并带参数1
[root@MiWiFi-R4CM-srv myShell]# sh controll_if.sh 1
You entered the number 1

7.2 case 语句

  1. 基本语法
case $变量名 in
	"值1")
		如果变了的值等于1,则执行程序1
		;;
	"值2")
    	如果变量的值等于2,则执行程序2
    	;;
    ........	
esac    
  1. 实操案例:

新建control_case.sh,内容如下

#!/bin/bash
case $1 in
"1")
        echo "You entered the number 1"
;;
"2")
        echo "You entered the number 2"         
;;
esac

执行control_case.sh

[root@MiWiFi-R4CM-srv myShell]# bash control_case.sh  1
You entered the number 1

7.3 for循环

  1. 基本语法1
for ((初始值;循环控制条件;变量变化)) 
do
    command1
    command2
    ...
    commandN
done

实操案例:新建一个control_for.sh,内容如下

#!/bin/bash
result=0
for((i=1;i<=100;i++))
do
        result=$[$result+$i] 
done
echo $result
  1. 基本语法2
for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

实操案例:

  • 打印所有输入参数1

创建shell脚本control_for_one.sh,内容如下

#!/bin/bash
# $* 任意参数(是个整体)
for i in $*
do 
        echo " I love $i"
done

# $@ 任意参数(逐个区分)
for j in $@
do 
        echo " I love $j"
done

执行shell control_for_one.sh

[root@MiWiFi-R4CM-srv myShell]# sh control_for_one.sh a b c d e 
 I love a
 I love b
 I love c
 I love d
 I love e
  • 打印所有输入参数2

实操案例:

#!/bin/bash
# $*与$@ 不加双引号时看不出来区别
for i in $*
do 
        echo " I love $i"
done

for j in $@
do 
        echo "I love $j"
done

echo "====================================="

# $*与$@ 加双引号时区明显
for m in "$*"
do 
        echo "I love $m"
done 

for n in "$@"
do 
        echo "I love $n"
done

执行结果

[root@MiWiFi-R4CM-srv myShell]# sh control_for_one.sh a b c d e 
 I love a
 I love b
 I love c
 I love d
 I love e
I love a
I love b
I love c
I love d
I love e
=====================================
I love a b c d e
I love a
I love b
I love c
I love d
I love e

7.4 while 循环

  1. 基本语法
while [条件表达式]
do
	#code
done	
  1. 实操案例:请1+100的和

创建control_while.sh,内容如下

#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
do
        s=$(($s+$i))    
        i=$(($i+1))
done
echo $s

执行

[root@MiWiFi-R4CM-srv myShell]# sh control_while.sh 
5050

7.5 read读取控制台输入

  1. 基本语法

read [选项] [参数]

选项:

  • -p:指定读取值是的提示符;
  • -t:指定读取值时等待的时间(单位:秒)

参数:

变量:指定读取的变量名

  1. 实操案例:
  • 提示10秒内,读取控制台输入的名称;10秒后失效

新建read.sh,内容如下

#!/bin/bash 
read -t 10 -p "Please enter your name in ten second " NAME
echo $NAME

执行

# 10 秒内输入 aa
[root@MiWiFi-R4CM-srv myShell]# bash read.sh 
Please enter your name in ten second aa 
aa
# 10 秒内再输入 cc
[root@MiWiFi-R4CM-srv myShell]# cc
cc: 致命错误:没有输入文件
编译中断。
[root@MiWiFi-R4CM-srv myShell]# 
文章来源:https://blog.csdn.net/yuanjinshenglife/article/details/135688216
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。