shell脚本编程

文章目录

一、什么是shell

1、简介

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

简单来说,Shell就是用户与操作系统之间的命令解释器

image-20240509233348028

2、常见的shell

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

我们关注Bash,由于易用和免费,Bash在日常工作中被广泛使用

同时,Bash 也是大多数Linux 系统默认的 Shell。

3、查看当前正在使用的shell

1、查看环境变量

echo $SHELL

image-20240510165350996

2、通过进程信息查看

ps | grep $$ | awk '{print $4}'

image-20240510170523729

3、/etc/passwd文件查看

grep ^$(whoami) /etc/passwd | awk -F "/" '{print $4}'

image-20240510170755346

二、shell脚本注意事项

1、Shebang行

#!后面紧接解释器的绝对路径

例如,使用bash时应在脚本第一行指明:
#!/bin/bash

2、注释

注释本质上还是为了增加脚本的可读性

注释包括以下部分:

shebang
脚本的参数
脚本的用途
脚本的注意事项
脚本的写作时间,作者,版权等
各个函数前的说明注释
一些较复杂的单行命令注释

3、缩进

#常见的缩进有"soft tab"和"hard soft"两种

# soft tab就是使用n个空格进行缩进(n通常是2或4)

# hard tab就是指真实的”\t”字符

4、日志与回显

#添加日志信息方便我们后续排查错误
#展现在终端的内容可以通过重定向选择性的展示,只保留重要的信息等

三、如何执行shell脚本

1、source

source Filename

在当前shell中执行

脚本文件无需可执行权限

2、bash/sh/zsh

bash Filename
sh Filename
zsh Filename
......

使用各自的命令解释器执行文件

子shell环境执行脚本

脚本文件无需可执行权限

3、./

#两种情况

#第一种情况(执行当前目录下的脚本文件)
./Filename

#第二种情况(脚本文件的绝对路径)
./Path/to/Filename

都需要脚本文件具有可执行权限

第一种情况在子shell环境下执行

第二种情况在当前shell环境下执行

四、shell变量

1、系统变量

#查看系统变量和用户定义的变量
set

#显示环境变量命令,可以查到全局变量
env

#显示环境变量命令,可以查到全局变量
printenv
系统变量作用
$HOME用户的主目录
$PWD当前工作目录的绝对路径
$USER$LOGNAME当前用户的用户名
$SHELL当前用户的默认Shell
$PATH查找可执行文件的路径列表,以冒号为分割
$RANDOM生成一个随机数
$SECONDSShell启动后经过的秒数
$TERM打印当前的终端类型
$HOSTNAME显示当前主机名
RANDOM生成随机(0-32767)整数

2、自定义变量

2.1、变量定义的规则
  • 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
  • 不能使用特殊字符、标点符号、bash中的关键字
  • 等号两侧不能有空格
  • 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
  • 变量的值如果有空格,需要使用双引号或者单引号括起来
2.2、定义变量

等号两侧不能有空格

格式:变量名=值

user_name=misaki
echo $user_name

image-20240511101721286

验证了等号两侧不能有空格

2.3、赋值时使用的符号
2.3.1、使用双引号""
[root@localhost ~]# name=misaki
[root@localhost ~]# TEXT="hello $name"
[root@localhost ~]# echo $TEXT
hello misaki

image-20240511105946713

2.3.2、使用单引号’’
[root@localhost ~]# test='ls -1'
[root@localhost ~]# echo $test
ls -1

image-20240511111650329

2.3.3、使用反引号``
[root@localhost ~]# test=`ls -1`
[root@localhost ~]# echo $test
anaconda-ks.cfg

image-20240511110956302

2.3.4、使用$()
[root@localhost ~]# test=$(ls -1)
[root@localhost ~]# echo $test
anaconda-ks.cfg

image-20240511111013537

2.3.5、区别
1、双引号允许变量扩展和命令替换发生,但保留内部的空白字符(如空格和制表符)

2、单引号阻止所有形式的扩展和解析,因此$(ls -1)被视为普通文本而非命令。

3、反引号与$(...)功能相同,执行命令替换。但现代Shell脚本推荐使用$(...),因为它在嵌套和与其它引号配合使用时更清晰。
2.4、给变量重新赋值

只需再次使用相同的变量名并赋予新的值即可给已经存在的用户自定义变量重新赋值

[root@localhost ~]# user_name=zhangsan
[root@localhost ~]# echo $user_name
zhangsan
[root@localhost ~]# user_name=lisi
[root@localhost ~]# echo $user_name
lisi

image-20240511113306929

2.5、撤销变量的值

格式:unset 变量

[root@localhost ~]# unset user_name
[root@localhost ~]# echo $user_name

image-20240511113749869

2.6、静态变量

格式:readnoly 变量

静态变量不能unset(撤销)

[root@localhost ~]# readonly n1=1
[root@localhost ~]# echo $n1
1
[root@localhost ~]# unset n1
-bash: unset: n1: 无法反设定: 只读 variable

image-20240511122500040

2.7、全局变量

格式:export 变量名
可以通过这种方法把变量提升为全局变量,可供其它Shell程序使用

[root@localhost ~]# name=misaki
[root@localhost ~]# echo $name
misaki
[root@localhost ~]# bash
[root@localhost ~]# ps -f
UID         PID   PPID  C STIME TTY          TIME CMD
root       8164   8160  0 12:42 pts/1    00:00:00 -bash
root       8193   8164  0 12:43 pts/1    00:00:00 bash
root       8204   8193  0 12:43 pts/1    00:00:00 ps -f
[root@localhost ~]# echo $name

[root@localhost ~]# exit
exit
[root@localhost ~]# export name
[root@localhost ~]# bash
[root@localhost ~]# ps -f
UID         PID   PPID  C STIME TTY          TIME CMD
root       8164   8160  0 12:42 pts/1    00:00:00 -bash
root       8205   8164  0 12:43 pts/1    00:00:00 bash
root       8216   8205  0 12:43 pts/1    00:00:00 ps -f
[root@localhost ~]# echo $name
misaki

image-20240511124447714

最开始在父shell中声明了变量name值为misaki
随后启动子shell打印输出变量name的值发现没有
紧接着回到父shell中将变量name提升为全局变量
最后再启动子shell打印变量name发现在和父shell中输出的值一样

3、特殊变量

特殊变量功能
$0当前脚本的文件名
$1, $2, …, $n传递给脚本的参数,其中 n 代表参数的位置,从1开始计数
$#传递给脚本的参数个数
$*将所有参数的内容看成一个整体返回
$$当前Shell脚本的进程ID(PID)
$!最后一个后台进程的PID
$?上一个命令或函数的退出状态码(0表示成功,非0表示失败)

五、逻辑判断运算符

1、文件测试运算符

用于检查与文件相关的条件,也适用于目录和其他类型的文件测试。

1.1、存在性及类型测试:
  • ‐a FILE :文件存在性测试,存在为真,否则为假
  • ‐b FLIE:是否存在且为块设备文件;
  • ‐c FILE:是否存在且为字符设备文件;
  • ‐d FILE:是否存在且为目录文件;
  • ‐f FILE:是否存在且为普通文件;
  • ‐h FILE 或 ‐L FILE : 存在且为符号链接文件;
  • ‐p FIEL :是否存在且为命名管道文件;
  • ‐S FILE:是否存在且为套接文件;
1.2、文件权限测试:
  • ‐r FILE:是否存在且可读
  • ‐w FILE:是否存在且可写
  • ‐x FILE:是否存在可执行
1.3、文件特殊权限测试:
  • ‐u FILE:是否存在且拥有suid权限;
  • ‐g FILE:是否存在且拥有sgid权限;
  • ‐k FILE:是否存在且拥有sticky权限;
1.4、文件大小测试:
  • ‐s FILE:是否存在且非空
1.5、文件是否打开:
  • ‐fd:fd表示文件描述符是否已经打开且与某终端相关
  • ‐N FILE:文件自动上一次读取之后是否被修改过;
  • ‐O FILE:当前用户是否为文件的属主;
  • ‐G FILE:当前有效用户是否为文件数组;
1.6、双目测试:
  • FILE1 ‐ef FILE2 :FILE1与FILE2是否指向同一个设备上的相同inode
  • FILE1 ‐nt FILE2:FILE1是否新于FILE2
  • FILE1 ‐ot FILE2:FILE1是否旧于FILE2

2、字符串比较运算符

==:是否等于 

>:是否大于 

<:是否小于

!=:是否不等于 

=~:左侧字符串是否能够被右侧的PATTERN所匹配,此表达式一般用于[[ ]]中 

‐z "STRING":测试字符串是否为空,空则为真,不空则为假 

‐n "STRING":测试字符串是否不空,不空则为真,空则为假

3、数值比较运算符

  • ‐gt:是否大于
  • ‐ge:是否大于等于
  • ‐eq:是否等于
  • ‐ne:是否不等于
  • ‐lt:是否小于
  • ‐le:是否小于等于

4、逻辑运算符

  • &&代表的意思是当前一个命令执行成功时会继续执行后续的命令,当前一个命令执行失败的时候不会执行后续的命令
  • ||代表的意思是当前一个命令执行成功时不会继续执行后续的命令,当前一个命令执行失败的时候会执行后续的命令
  • ! expr:如果expr的结果为假,则为真。
  • expr1 -a expr2:如果expr1和expr2都为真,则为真(逻辑与)。
  • expr1 -o expr2:如果expr1或expr2至少有一个为真,则为真(逻辑或)。

六、流程控制

1、条件选择执行语句if

1.1、单分支结构
if [ 条件表达式 ]; then
    条件为真时执行的命令
fi
1.1.1、示例:检查文件是否存在
#!/bin/bash
if [ -f "/etc/passwd" ]; then
        echo "The file exists."
fi

image-20240512091856539

1.2、双分支结构
if [ 条件表达式 ]; then
    条件为真时执行的命令
else
    条件为假时执行的命令
fi
1.2.1、示例:判断数字奇偶
#!/bin/bash
read -p "输入一个数字:" num
if [ $((num % 2)) -eq 0 ]; then
        echo "输入的数字是偶数"
else
        echo "输入的数字是奇数"
fi

image-20240512093250906

1.3、多分支结构
if [ 条件表达式1 ]; then
    条件1为真时执行的命令
elif [ 条件表达式2 ]; then
    条件1为假且条件2为真时执行的命令
else
    所有条件均为假时执行的命令
fi
1.3.1、示例:成绩等级判定
#!/bin/bash
read -p "输入你的成绩:" sorce
if [ "$sorce" -ge 90 ]; then
        echo "Grade: A"
elif [ "$sorce" -ge 80 ]; then
        echo "Grade: B"
elif [ "$sorce" -ge 70 ]; then
        echo "Grade: C"
elif [ "$sorce" -ge 60 ]; then
        echo "Grade: D"
else
        echo "Grade: F"
fi

image-20240512100045053

2、for循环语句

2.1. 列表遍历形式
for 变量名 in 列表
do
    命令序列
done
  • 变量名:在每次循环中用来存储当前遍历到的值。
  • 列表:可以是逗号分隔的值列表、文件名通配符(如*)、命令的输出(用反引号...$(...)包裹),或是任何能产生多个项目的序列。
2.1.1、示例:遍历数字列表、文件、命令
#!/bin/bash
#遍历数字列表
for i in 1 2 3 4 5
do
        echo $i
done
#遍历文件
for file in *.sh
do
        echo "Processing file: $file"
done
#遍历命令输出
for ip in $(hostname -I)
do
        echo "IP address: $ip"
done

image-20240512101046884

2.2、 序列生成形式(使用seq或brace expansion)
for 变量名 in $(seq 起始值 步长 结束值) 或 {起始值..结束值}
do
    命令序列
done
2.2.1、示例:生成序列
#!/bin/bash
#使用seq生成序列
echo for_seq
for i in $(seq 1 2 10)
do
        echo $i
done
#使用brace expansion
echo for_brace expansion
for n in {1..5}
do
        echo $n
done

image-20240512101727721

2.3、 C风格的for循环
for (( 表达式1; 表达式2; 表达式3 ))
do
    命令序列
done
  • 表达式1:初始化部分,通常用于设置循环变量的初始值。
  • 表达式2:条件表达式,当其值为真(非零)时继续循环。
  • 表达式3:更新部分,每次循环后执行,常用于改变循环变量的值。
2.3.1、示例:生成序列
#!/bin/bash
for (( i=1;i<5;i++ ))
do
        echo $i
done
[root@localhost Shell]# bash for_3.sh
1
2
3
4

image-20240512103306897

3、while循环语句

3.1、标准格式
while [条件表达式 ];
do
    命令序列
done
  • 条件表达式:一个命令或表达式,其退出状态决定循环是否继续。如果表达式的退出状态为0(真),则循环继续;否则,循环终止。
  • 命令序列:在每次循环中执行的命令集合。这些命令可以是一条或多条语句,通常用于改变循环控制变量的值,以确保循环最终能够结束,防止死循环。
3.1.1、示例:基础计数循环
#!/bin/bash
i=1
while [ $i -le 5 ]
do
    echo "This is loop number $i"
    i=$((i+1)) # 或 ((i++))
done

image-20240512103753911

3.2、结合read逐行处理文件
while read line; do
    循环体
done < /PATH/FROM/SOMEFILE

从标准输入读取文件中的每一行,并将其赋值给变量line

3.2.1、示例:读文件行
#!/bin/bash
count=0
while IFS= read -r line
do
        let count+=1
        echo " Line$count: $line"
done < /etc/passwd

image-20240512104948695

4、until循环语句

until循环会重复执行一系列命令,直到给定的条件变为真(即条件表达式的退出状态为0。

确保until循环中的条件最终能够变为真,以避免创建无限循环。

until [条件表达式]
do
    命令序列
done
4.1示例:计数到5
#!/bin/bash
i=0
until [ $i -ge 5 ]
do
        echo "Counter: $i"
        i=$((i+1))
done

image-20240512105758976

5、select循环语句

select语句一般用于选择,常用于创建选择菜单系统,让用户能够在命令行界面中进行选择。

select循环会显示一个由选项组成的列表,并允许用户输入对应数字来选择一个选项。

select 变量名 in 列表; do
    命令序列
done

6、case语句

case语句是一种多路分支控制结构,用于根据不同的条件执行不同的代码块。

它类似于其他编程语言中的switch语句,提供了一种优雅的方式来处理多条件判断。

case 变量或表达式 in
    模式1)
        命令序列1
        ;;
    模式2)
        命令序列2
        ;;
    ...
    *)
        默认命令序列(如果没有任何模式匹配时执行)
        ;;
esac
  • *):特殊模式,代表默认分支,当没有其他模式匹配时执行。
  • ;;:每个命令序列的结束标记。
  • esac:结束case语句的关键字,必须放在所有分支之后。
#结合select,case比较完整的类菜单格式如下:

select 变量名 in 列表; do
    case $变量名 in
        选项1)
            相应的命令序列
            ;;
        选项2)
            其他命令序列
            ;;
        *)
            默认或无效选项处理
            ;;
    esac
done
6.1、示例:星期几
#!/bin/bash

day_of_week=$(date +%u) # %u 返回1(星期一) 到7(星期日)

# 通过case语句匹配今天的星期并输出对应信息
case $day_of_week in
    1)
        echo "今天是星期一,一周的开始,努力工作!"
        ;;
    2)
        echo "星期二,继续加油!"
        ;;
    3)
        echo "过了星期三,翻过一座山,星期三愉快!"
        ;;
    4)
        echo "星期四,期待周末的到来!"
        ;;
    5)
        echo "星期五,马上就是周末啦,坚持一下!"
        ;;
    6|7) # 星期六和星期日一起处理
        echo "周末啦,好好休息,享受生活!"
        ;;
    *)
        echo "无法识别的日期格式,请检查date命令是否正常工作。"
        ;;
esac

# 脚本执行完case语句后自动退出
exit 0

image-20240512113742776

7、continue语句

continue语句是一个流程控制命令,用于跳过当前循环迭代中剩余的部分命令,直接开始下一次循环迭代(如果条件仍允许循环继续的话)

7.1、示例

假设我们有一个脚本,想要打印1到10之间的数字,但跳过偶数:

#!/bin/bash
for i in {1..10}; do
    if [ $((i % 2)) -eq 0 ]; then
        continue
    fi
    echo $i
done

image-20240511232407941

7.2、注意事项
  • 作用范围continue只影响最直接包围它的循环。如果在嵌套循环中使用continue,它只会跳过当前层次循环的剩余部分,不会影响外层循环。
  • 与break的区别break语句会立即终止整个循环,而不仅仅是当前迭代,直接跳出循环体。
  • 使用场景continue常用于在满足特定条件时略过循环体中某些不必要的操作,而继续执行后续的迭代,这对于过滤或跳过某些循环过程中的情况非常有用。

8、break语句

break语句是一个流程控制命令,用于提前退出循环结构,包括forwhileuntil循环以及select语句。

8.1、单层循环跳出
#!/bin/bash
for i in {1..5}; do
    if [ $i -eq 3 ]; then
        break
    fi
    echo "Number: $i"
done

image-20240511233306914

i等于3时,break语句执行,循环提前结束,因此只会打印1和2。

8.2、多层循环跳出
#!/bin/bash
for ((i=1; i<=3; i++)); do
    for ((j=1; j<=3; j++)); do
        if [ $i -eq 2 ] && [ $j -eq 2 ]; then
            break 2  # 跳出两层循环
        fi
        echo "i=$i, j=$j"
    done
done

image-20240511233808372

当内层循环的ij都等于2时,使用break 2跳出两层循环,因此不会打印i=2, j=2之后的任何组合。

七、数组

1、索引数组(数值索引)

1.1、定义与赋值

索引数组的元素由整数索引,从0开始

# 定义并初始化数组
myArray=(value1 value2 value3)

# 动态追加元素
myArray+=("value4")
1.2、访问元素
echo ${myArray[0]}	#输出第一个元素

image-20240512193414058

1.3、读取数组
echo "数组的元素为: ${myArray[*]}"

echo "数组的元素为: ${myArray[@]}"

image-20240512193730834

1.4、获取数组长度
echo "数组的长度为:${#myArray[*]}"

echo "数组的长度为:${#myArray[@]}"

image-20240512193852252

1.5、遍历数组
#!/bin/bash
myArray=(A B C D)
myArray+=("E")
echo "读取数组方式一(myArray[@]):"
for i in "${myArray[@]}"; do
        echo "$i"
done
echo "读取数组方式二(myArray[*]):"
for element in "${myArray[*]}"; do
        echo "$element"
done

image-20240512194737932

1.6、删除数组元素
1.6.1、删除数组所有元素
#!/bin/bash
myArray=(A B C D)
myArray+=("E")
echo "读取数组方式一(myArray[@]):"
for i in "${myArray[@]}"; do
        echo "$i"
done
echo "读取数组方式二(myArray[*]):"
for element in "${myArray[*]}"; do
        echo "$element"
done
echo "unset删除数组中所有元素"
unset myArray
echo ${myArray[@]}
echo ${#myArray[@]}

image-20240512204244136

1.6.2、删除数组中的指定元素
#!/bin/bash

# 初始化数组
myArray=(A B C D)

# 定义删除元素的函数(函数过会儿讲)
deleteElement() {
    local index=$1
    local i=0
    local newArray=()

    for element in "${myArray[@]}"; do
        if [ $i -ne $index ]; then
            newArray+=("$element")
        fi
        ((i++))
    done
    myArray=("${newArray[@]}")
}

# 调用函数删除索引为1的元素(记住数组索引从0开始)
deleteElement 1

# 打印修改后的数组验证结果
echo "${myArray[@]}"

image-20240512205539322

2、关联数组(字符串索引)

2.1、定义与赋值
#!/bin/bash
#直接赋值
declare -A assocArray1
assocArray1[sorce1]=95
assocArray1[sorce2]=85
assocArray1[sorce3]=75

#初始化时赋值
declare -A assocArray2=([sorce1]=100 [sorce2]=90 [sorce3]=80)

#追加元素
assocArray1[sorce4]=60

image-20240512214023815

2.2、访问元素
#!/bin/bash
#直接赋值
declare -A assocArray1
assocArray1[sorce1]=95
assocArray1[sorce2]=85
assocArray1[sorce3]=75

#初始化时赋值
declare -A assocArray2=([sorce1]=100 [sorce2]=90 [sorce3]=80)

#追加元素
assocArray1[sorce4]=60

#访问元素
echo "${assocArray1[sorce1]}"
echo "${assocArray2[sorce1]}"

image-20240512214259331

2.3、获取数组长度
#!/bin/bash
#直接赋值
declare -A assocArray1
assocArray1[sorce1]=95
assocArray1[sorce2]=85
assocArray1[sorce3]=75

#初始化时赋值
declare -A assocArray2=([sorce1]=100 [sorce2]=90 [sorce3]=80)

#追加元素
assocArray1[sorce4]=60

#获取数组长度
echo ${#assocArray1[@]}
echo ${#assocArray1[*]}
echo ${#assocArray2[@]}
echo ${#assocArray2[*]}

image-20240512214437910

2.4、遍历函数
#!/bin/bash
# 直接赋值
declare -A assocArray1
assocArray1[sorce1]=95
assocArray1[sorce2]=85
assocArray1[sorce3]=75

# 初始化时赋值
declare -A assocArray2=([sorce1]=100 [sorce2]=90 [sorce3]=80)

# 追加元素
assocArray1[sorce4]=60

# 遍历关联数组1
echo "遍历assocArray1:"
for key in "${!assocArray1[@]}"; do
    echo "$key: ${assocArray1[$key]}"
done

# 遍历关联数组2
echo "遍历assocArray2:"
for key in "${!assocArray2[@]}"; do
    echo "$key: ${assocArray2[$key]}"
done

image-20240512215219126

2.5、删除数组元素
#!/bin/bash
# 直接赋值
declare -A assocArray1
assocArray1[sorce1]=95
assocArray1[sorce2]=85
assocArray1[sorce3]=75

# 初始化时赋值
declare -A assocArray2=([sorce1]=100 [sorce2]=90 [sorce3]=80)

# 追加元素
assocArray1[sorce4]=60

# 删除数组所有元素
declare -A assocArray1=()

# 删除数组指定元素
unset assocArray2[sorce2]

# 打印数组1验证(此处应该为空,因为已清空)
echo "打印数组1"
for key1 in "${!assocArray1[@]}"; do
    echo "成绩: $key1, 值: ${assocArray1[$key1]}"
done

# 打印数组2验证
echo "打印数组2"
for key2 in "${!assocArray2[@]}"; do
    echo "成绩: $key2, 值: ${assocArray2[$key2]}"
done

image-20240512221324957

八、函数

Shell脚本中的函数是组织和复用代码的关键组成部分,允许将一系列命令组合成一个单元,便于多次调用

1、函数的格式

1.1、格式一
function_name() {
    commands...
}
function_name	#调用函数
1.2、格式二
function function_name {
    commands...
}
function_name	#调用函数

2、参数传递

函数可以接受任意数量的参数,这些参数在函数体内部可以通过位置参数(如 $1, $2, …) 访问,$0 通常代表函数名。

#!/bin/bash
greet(){
        echo "Hello $1!"
}
greet "World"
[root@localhost Shell]# bash greet.sh
Hello World!

image-20240512222901349

3、返回值

函数可以通过return语句返回一个退出状态码,这个状态码通常是一个整数,用来表示函数的执行结果或状态。

在脚本中,可以用 $? 来访问最近的命令或函数的退出状态码。

#!/bin/bash
funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
read aNum
        echo "输入第二个数字: "
read anotherNum
        echo "两个数字分别为 $aNum$anotherNum !"
        return $(($aNum+$anotherNum))
}
funWithReturn
        echo "输入的两个数字之和为 $? !"
#可以使用$?来获取返回值

image-20240512223905744

九、用户交互(read)

1、基本用法

#!/bin/bash
#读取一行输入并赋值给变量REPLY
read
echo "您输入的是: $REPLY"xxxxxxxxxx read #!/bin/bash#读取一行输入并赋值给变量REPLYreadecho "您输入的是: $REPLY"

image-20240512225111738

2、显示提示信息,等待用户输入(-p)

#!/bin/bash
read -p "请输入你的名字: " name
        echo "你好,$name!"

image-20240512225456881

3、限制等待时间(-t)

#!/bin/bash
read -t 5 -p "请在5秒内输入你的年龄: " age
if [ $? -eq 142 ]; then
    echo "超时,没有输入。"
else
    echo "你的年龄是: $age"
fi

image-20240512225654799

4、启用行编辑功能(-e)

启用行编辑功能。这意味着用户可以使用Backspace键删除输入错误的字符,使用左右箭头键移动光标等。

此选项依赖于终端支持。

read -e -p "请输入信息: " input

5、指定读取的字符数(-n)

限定读取的字符数,而非直到遇见换行符。

#!/bin/bash
read -n 2 -p "请输入两个字符: " twoChars

image-20240512230713031

6、静默模式(-s)

静默模式,不显示用户输入的内容,适用于密码等敏感信息的输入

#!/bin/bash
read -s -p "请输入密码: " password
echo "密码已输入。"

image-20240512231042477

7、指定输出结束的分隔符(-d)

#!/bin/bash
read -d ';' -p "输入多条信息,分号停止: " multiLine

image-20240512231612671

8、数组赋值(<<<)

#!/bin/bash
read -a fruits <<< "apple banana cherry"
echo "${fruits[2]}"  # 输出 "cherry"

image-20240512231854627

十、调试脚本

1、-x进行命令追踪

运行命令: bash -x debug_1.sh

#!/bin/bash
for i in {1..6}
do
        echo $i
done
echo "Script Executed"

image-20240512233436469

2、-v查看命令和结果

运行命令: bash -v debug_2.sh

#!/bin/bash
#set -v  # 开始详细输出
echo "当前日期是: $(date)"
#set +v  # 结束详细输出

image-20240512233745709

3、-n进行语法检查

#!/bin/bash
for i in {1..6}
do
echo "输出1-6: $i
done

image-20240512234035024

4、-e进行错误处理

#!/bin/bash
set -e  # 遇到错误立即退出
echo "尝试执行一个不存在的命令..."
ld
echo "这行不会被执行,因为上一行命令失败了"

image-20240512234453526

5、查看脚本的退出状态码

  • 0 表示成功;
  • 非零值通常表示某种错误。
#!/bin/bash
cd /debug  # 故意执行一个失败的命令
echo "上一个命令的退出状态码是: $?"

image-20240512235017183

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值