shell编程(完整版)

目录

一、shell脚本解释器

二、shell脚本的执行

三、变量的使用

四、永久环境变量

按用户设置永久环境变量

文件路径:

示例步骤:

删除永久环境变量

五、脚本程序传递参数怎么实现

六、用编程进行数学运算

shell中利用expr进行运算

运算与变量结合

1. 变量赋值和基本运算

2. 使用expr进行运算

3. 变量拼接

4. 条件判断结合变量

七、在shell脚本中与用户交互

利用read name age

利用raed -p

利用read -t 10 -p

利用read -n 3 -t 10 -p

八、用脚本模拟编写

九、关系运算符

十、字符串运算符和逻辑运算符

字符串运算符

判断其是否大小写敏感

逻辑运算符之布尔运算符

余运算

十一、if条件判断

基本if语句

if单行写法

if-else语句

if-elif-else语句

条件判断中的比较操作符

使用(( ... ))进行数值比较

示例

十二、for循环

基本for循环

for循环单行写法

示例

for循环与命令行参数

for循环与序列

C风格的for循环

注意事项

十三、while循环

基本while循环

while循环单行写法

示例

示例1:使用while循环读取用户输入

示例2:使用while循环处理数字序列

注意事项

十四、until循环

示例

until 和 while 的区别

十五、case语句

基本语法

示例

1. 简单的 case 语句

2. 使用通配符

3. 处理多个匹配

case 和 if 的比较

case 语句:

if 语句:

十六、基本函数

基本函数定义和调用

1. 定义一个简单的函数

2. 函数接收参数

3. 返回值

4. 使用 return 返回状态码

5. 局部变量和全局变量

6. 函数的递归调用

7. 函数中的错误处理

8. 函数的默认参数


声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章

声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险,并遵循相关法律法规。

一、shell脚本解释器

1.#! /bin/bash

2.#! /bin/dash

3.#! /bin/sh

不管使用哪种脚本解释器最后还是调用的dash

二、shell脚本的执行

echo hello world 1.sh

第一种方法./1.sh(给1.sh授予权限)

查看是否拥有执行的权限,表示脚本是否可以进行执行

使用`ls -l 1.sh进行查看,然后用chomd给其加权chmod 777 1.sh

第二种方法直接使用解释器

sh 1.sh

bash 1.sh

dash 1.sh

第三种方法使用source命令

source 1.sh

使用这种方法若是在脚本中加上ls会让效果更明显,因为这个命令会让输出的结果颜色加深。

三、变量的使用

1.变量声明和定义

name=“xiaoyu”

echo $name

age=27

echo $age

echo my name is $name,and my age is $age years old

一般来说加双引号和不加的效果是一样的

echo “my name is $name,and my age is $age years old”

但是加单引号就不会解析变量直接输出所有字符串

echo ‘my name is $name,and my age is $age years old’

2.变量拼接

echo my name is $name,and my age is $ageyears old

加了$后面的就会被当成是一个变量,然后找不到这个变量,这个变量即会输出为空。

解决办法将变量用双引号括起来,它就会做一个区分

echo “my name is $name,and my age is {$age}years old”

用""也是可以的

echo “my name is $name,and my age is "$age"years old”

3.变量的命名规则

变量是由数字,字符串,下划线组成,但是不能以数字为开头,例如9name这种不行,变量中间也不能有空格,可以用下划线代替空格,如long_yu="xiaoyu"

4.查看变量

set | grep name

查看变量名为name的变量

四、永久环境变量

按用户设置永久环境变量

将变量写入用户的配置文件,适用于单个用户。

文件路径:
  • Bash 用户:修改 ~/.bashrc~/.bash_profile 文件。

  • Zsh 用户:修改 ~/.zshrc 文件。

  • 通用用户:修改 ~/.profile 文件。

示例步骤:
  1. 打开配置文件:

    bash
    nano ~/.bashrc
  2. 添加环境变量:

    bash
    export VARIABLE_NAME="value"
    export PATH=$PATH:/your/new/path
  3. 保存并退出(在 nano 中,按 Ctrl+O 保存,按 Ctrl+X 退出)。

  4. 让变量立即生效:

    bash
    source ~/.bashrc
删除永久环境变量
  1. 从对应文件中删除变量。

  2. 刷新配置:

    bash复制代码source ~/.bashrc  # 用户级别
    source /etc/profile  # 系统级别

五、脚本程序传递参数怎么实现

echo 执行的文件名是:$0

echo 第一个参数是:$1

echo 传递的参数作为一个字符显示:$*

echo 传递的参数作为每个字符串显示:$@

echo 传递到脚本的参数个数是:$#

echo 最后命令的退出状态:$?

echo 脚本运行的当前进程ID:$$

  1. $0:这个变量代表当前执行的脚本文件的名称。如果脚本是通过链接或者绝对路径执行的,那么它将显示完整的路径;如果是通过相对路径执行的,那么它将显示相对路径。

    echo "执行的文件名是:$0"
  2. $1:这个变量代表传递给脚本的第一个参数。在命令行上调用脚本时,紧跟在脚本名后面的第一个值就是 $1。

    echo "第一个参数是:$1"
  3. $*:这个变量代表传递给脚本的所有参数,它们会被合并成一个单一的字符串。参数之间的分隔符默认是第一个字符(通常是空格)。

    echo "传递的参数作为一个字符显示:$*"
  4. $@:这个变量也代表传递给脚本的所有参数,但每个参数都会被视为独立的字符串。这意味着如果参数中包含空格,它们会被正确地处理。

    echo "传递的参数作为每个字符串显示:$@"
  5. $#:这个变量代表传递给脚本的参数的个数,不包括脚本本身的名称。

    echo "传递到脚本的参数个数是:$#"
  6. $?:这个变量代表上一个执行的命令的退出状态。如果命令成功执行,通常退出状态是 0;如果命令执行失败,退出状态是非 0 的值。

    echo "最后命令的退出状态:$?"
  7. $$:这个变量代表当前脚本运行的进程 ID(PID)。

    echo "脚本运行的当前进程ID:$$"

六、用编程进行数学运算

shell中利用expr进行运算

错误:expr 5+10 会回显 5+10

正确:expr 5 + 10 就会显示15了

以上方法适用于加法减法

乘法:

错误:expr 5 * 10 会报错

正确:expr 5 * 10 就会显示50了 需要使用\进行转义

除法:

正确:expr 10 / 5 会显示2

取余:

正确:expr 10 % 4 会显示2

运算与变量结合

1. 变量赋值和基本运算

#!/bin/bash
​
# 定义变量
a=5
b=10
​
# 进行基本的算术运算
sum=$((a + b))        # 加法
difference=$((a - b))  # 减法
product=$((a * b))    # 乘法
quotient=$((a / b))    # 除法
remainder=$((a % b))   # 取余
​
# 输出结果
echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"
echo "Remainder: $remainder"

2. 使用expr进行运算

expr是一个强大的工具,用于在Shell脚本中进行复杂的表达式求值。

#!/bin/bash
​
a=5
b=10
​
# 使用expr进行运算
sum=$(expr $a + $b)
difference=$(expr $a - $b)
product=$(expr $a \* $b)  # 注意乘法需要转义
quotient=$(expr $a / $b)
remainder=$(expr $a % $b)
​
# 输出结果
echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"
echo "Remainder: $remainder"

3. 变量拼接

变量拼接是将多个变量或字符串组合成一个单一的字符串。

#!/bin/bash
​
first_name="John"
last_name="Doe"
​
# 变量拼接
full_name="${first_name} ${last_name}"
​
echo "Full Name: $full_name"

4. 条件判断结合变量

条件判断经常与变量结合使用,以控制脚本的流程。

#!/bin/bash

num=25

if [ $num -gt 20 ]; then
    echo "Number is greater than 20"
else
    echo "Number is not greater than 20"
fi

七、在shell脚本中与用户交互

利用read name age

read name age

指定变量信息xiaoyu 26

然后我们利用

echo $name 来接收用户输入

echo $age 来接收用户输入

利用raed -p

先进入bash环境

read -p "请输入你的姓名" name

输入:xiaoyu

echo $name 来接收用户输入

利用read -t 10 -p

read -t 10 -p "请输入你的姓名" name

-t(指定时间)

如果用户在10s内没有进行输入,程序会自动退出,反之就会执行程序

利用read -n 3 -t 10 -p

read -n 3 0t 10 -p "请输入你的姓名" name

-n(限制用户输入的字符数量)

八、用脚本模拟编写

vim 1.sh
read -p "请输入你的姓名" name
echo "你输入的姓名是:$name,请你确认!"

九、关系运算符

vim o.sh

首先,定义两个变量,然后通过if条件判断来进行两个简单的条件判断,再接入关系运算符

-eq(相等)

-lt(小于)

-gt(大于)

-ne(不等于)

else(反转)

只能对数值进行判断,无法对某个字符串进行判断

脚本如下

num1=78
num2=89
if [$num1 -eq $num2] : then
    echo 相等
else    
    echo 不相等
fi

[]可以换成test进行测试

num1=78
num2=89
if test $num1 -eq $num2 : then
    echo 相等
else    
    echo 不相等
fi

十、字符串运算符和逻辑运算符

字符串运算符

首先打开终端,利用vim打开u.sh

str1="hello"
str2="hello"
if [ “$str1” = “$str2” ]; then
    echo True
else
    echo flase
fi

接着sh u.sh运行脚本,看字符串是否相等

判断其是否大小写敏感

vim u.sh进入脚本并修改,将hello修改为Hello,然后再运行脚本,得出结果是不相等,所以shell编程中大小写敏感

  • -z(检查字符串的长度是否为0)

str1="hello"
str2="hello"
if [ -z ""$str1" ]; then
    echo True
else
    echo flase
fi

运行结果返回flase长度不为0

  • -n(检查字符串长度是否不为0)与-z相反

逻辑运算符之布尔运算符

num1=9
#num2=19(如果后续不需要用到num2,可删除这一行)
if ["$num1"!= "9"]; then
    echo num1不等于9
else
    echo num1等于9
fi

余运算

num1=9
num2=19
#使用-a作为逻辑与运算符来正确连接两个条件,并给变量加上双引号确保正确
if [ $num1 != "9" -a $num2 -lt "20" ];then
    echo True
else
    echo Flase
fi

同时满足$num1 !=9 $num2 -lt 20 输出true 不满足返回flase

num1=9
num2=19
#使用-o作为逻辑或运算符来正确连接两个条件,并给变量加上双引号确保正确
if [ $num1 != "9" -o $num2 -lt "20" ];then
    echo True
else
    echo Flase
fi

与之相反的参数是-o参数 只需要满足其中一个就可以返回true 两个都不满足就返回flase

十一、if条件判断

首先用vim打开一个脚本k.sh

vim k.sh

#定义变量
a=10
b=20
#进行条件判断
if [ "$a" -eq "$b" ];then
    echo "a=b"
elif [ "$a" -gt "$b"];then
    echo "a>b"
else
    echo "没有符合上述条件"
fi

基本if语句

if condition
then
    command1
    command2
    ...
    commandN
fi
  • condition:条件表达式,如果条件为真(返回状态码0),则执行then部分的命令。

  • command1 command2 ... commandN:当条件为真时执行的一系列命令。

  • fi:结束if语句。

if单行写法

if [ $(ps -ef | grep -c "bash") -gt 1 ]; then echo "true"; fi
  • $(...):命令替换,执行括号内的命令,并将输出替换到当前位置。

  • [...]:条件测试,用于判断括号内的表达式是否为真。

if-else语句

if condition
then
    command1
    command2
    ...
    commandN
else
    command
fi
  • else:如果条件为假(返回状态码非0),则执行else部分的命令。

if-elif-else语句

if condition1
then
    command1
elif condition2
then 
    command2
else
    commandN
fi
  • elif:如果condition1为假,则会检查condition2,以此类推,直到找到第一个为真的条件。

条件判断中的比较操作符

  • >:大于,使用-gt。

  • <:小于,使用-lt。

  • ==:等于,使用-eq。

  • !=:不等于,使用-ne。

使用(( ... ))进行数值比较

if (( a > b )); then
    echo "a is greater than b"
fi
  • 在(( ... ))中,可以直接使用>和<进行数值比较。

示例

for i in 1 2 3 4 5
do 
    echo "the var is $i"
done

这段代码会依次打印出:

the var is 1
the var is 2
the var is 3
the var is 4
the var is 5

十二、for循环

基本for循环

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
  • var:循环变量,用于存储当前迭代的值。

  • item1 item2 ... itemN:一个序列或列表,var将依次取这些值。

  • command1 command2 ... commandN:每次迭代执行的命令序列。

  • do和done:分别标记for循环的开始和结束。

for循环单行写法

for var in item1 item2 ... itemN; do command1; command2... done;

示例

for i in 1 2 3 4 5
do 
    echo "the var is $i"
done

这段代码会依次打印出:

the var is 1
the var is 2
the var is 3
the var is 4
the var is 5

for循环与命令行参数

for循环还可以使用命令行参数:

for var in "$@"
do
    command
done

在这个例子中,$@代表所有传递给脚本的参数,var将依次取这些参数的值。

for循环与序列

for循环可以与序列一起使用,例如:

for i in {1..5}
do
    echo "Number $i"
done

这将打印:

Number 1
Number 2
Number 3
Number 4
Number 5

C风格的for循环

在某些Shell(如Bash)中,也可以使用C风格的for循环:

for ((i=0; i<5; i++))
do
    echo "Number $i"
done

这将打印:

Number 0
Number 1
Number 2
Number 3
Number 4

注意事项

  • for循环中的命令可以是任何有效的Shell命令或语句。

  • in列表可以包含替换、字符串和文件名。

  • 如果in列表被省略,for循环将使用命令行的位置参数。

十三、while循环

基本while循环

while condition
do
    command1
    command2
    ...
    commandN
done
  • condition:条件表达式,只要这个条件为真,循环就会继续执行。

  • command1 command2 ... commandN:只要条件为真,这些命令就会被重复执行。

  • do和done:分别标记while循环的开始和结束。

while循环单行写法

while condition; do command1; command2... done

示例

示例1:使用while循环读取用户输入
echo "Enter 'q' to quit."
while read -r input
do
    if [[ "$input" == "q" ]]; then
        break
    fi
    echo "You entered: $input"
done

这个循环会不断读取用户输入,直到用户输入q。

示例2:使用while循环处理数字序列
i=0
while [ $i -lt 5 ]
do
    echo "Number $i"
    ((i++))
done

这个循环会打印数字0到4。

注意事项

  • condition可以是任何命令或表达式,只要它返回状态码0,循环就会继续。

  • 使用break命令可以提前退出循环。

  • 使用continue命令可以跳过当前迭代,继续执行下一次循环。

  • 确保循环有一个明确的退出条件,否则可能会造成无限循环。

十四、until循环

在Shell编程中,until 时执行循环体。

bash复制代码until [ 条件 ]
do
    
    
# 循环体
​
d
done
​
``

until 循环会

示例

  1. 基本例子: 打印数字count 达到 5。

bash复制代码count=1
until [ $count -gt 5 ]
do
    echo $count
    ((count++))
​
    ((co
​
    (
​
  
done

解释

  • 循环开始时,count 的值为 1。

  • 条件是 count -gt 5,即 count 是否大于 5。当 count 小于或等于 5 时,循环体继续执行。

  • 每次循环后,count 会增加 1。

输出结果:

复制代码1
2
3
4
5
  1. 判断文件是否存在:直到文件存在时退出。

bash复制代码until [ -f /path/to/file ]
do
    echo "文件还不存在,等待中..."
    sleep 2
done
echo "文件已存在,继续执行"

解释

  • 每隔 2 秒检查一次文件是否存在,直到文件存在时,退出循环。

untilwhile 的区别

  • until 循环是当条件为假时才执行,而 while 循环是当条件为真时才执行。

例如:

bash复制代码# while 例子:当条件为真时执行
while [ $count -lt 5 ]
do
    echo $count
    ((count++))
done
​
# until 例子:当条件为假时执行
count=1
until [ $count -gt 5 ]
do
    echo $count
    ((count++))
done

十五、case语句

基本语法

bash复制代码case 变量 in
    pattern1)
        # 当变量匹配 pattern1 时执行的命令
        ;;
    pattern2)
        # 当变量匹配 pattern2 时执行的命令
        ;;
    *)
        # 默认情况,如果变量不匹配任何模式时执行的命令
        ;;
esac
  • 变量 是你要检查的变量。

  • pattern1, pattern2 等是模式,可以是文字、通配符(例如 *)或正则表达式。

  • ;; 用于结束每个匹配的执行块。

  • * 是一个通配符,表示所有其他没有匹配的情况,相当于 default

示例

1. 简单的 case 语句
bash复制代码echo "请输入一个数字:"
read num
​
case $num in
    1)
        echo "你输入的是数字 1"
        ;;
    2)
        echo "你输入的是数字 2"
        ;;
    3)
        echo "你输入的是数字 3"
        ;;
    *)
        echo "你输入的不是 1, 2 或 3"
        ;;
esac

解释

  • 程序提示用户输入一个数字,然后根据输入的值匹配不同的模式。

  • 如果输入的是 1,2 或 3,程序会分别输出相应的信息;否则输出默认信息。

2. 使用通配符
bash复制代码echo "请输入一个文件名:"
read filename
​
case $filename in
    *.txt)
        echo "这是一个文本文件"
        ;;
    *.jpg | *.png)
        echo "这是一个图片文件"
        ;;
    *)
        echo "无法识别的文件类型"
        ;;
esac

解释

  • 这个示例中,case 语句根据文件名的扩展名来判断文件类型。

  • 如果文件名以 .txt 结尾,输出“这是一个文本文件”;如果是 .jpg.png,则输出“这是一个图片文件”;其他文件类型则输出“无法识别的文件类型”。

3. 处理多个匹配
bash复制代码echo "请输入一个字符:"
read char
​
case $char in
    [a-z])
        echo "你输入的是一个小写字母"
        ;;
    [A-Z])
        echo "你输入的是一个大写字母"
        ;;
    [0-9])
        echo "你输入的是一个数字"
        ;;
    *)
        echo "你输入的不是字母或数字"
        ;;
esac

解释

  • case 语句根据用户输入的字符进行分类。

  • [a-z] 匹配小写字母,[A-Z] 匹配大写字母,[0-9] 匹配数字。

caseif 的比较

case 语句的优势在于它能简洁地处理多种条件,而 if 语句通常用于两种条件或逻辑较为复杂的情况。对于多重条件判断,case 语句通常更加清晰和简洁。

例如,以下两种写法是等价的:

case 语句:
bash复制代码case $color in
    red)
        echo "红色"
        ;;
    blue)
        echo "蓝色"
        ;;
    green)
        echo "绿色"
        ;;
    *)
        echo "未知颜色"
        ;;
esac
if 语句:
bash复制代码if [ "$color" = "red" ]; then
    echo "红色"
elif [ "$color" = "blue" ]; then
    echo "蓝色"
elif [ "$color" = "green" ]; then
    echo "绿色"
else
    echo "未知颜色"
fi

十六、基本函数

基本函数定义和调用

在 Shell 中,函数的基本语法如下:

bash复制代码function 函数名 {
    # 函数体
    # 这里放你希望执行的命令
}
​
# 或者简化版本
函数名() {
    # 函数体
}

1. 定义一个简单的函数

bash复制代码my_function() {
    echo "Hello, World!"
}
​
# 调用函数
my_function

解释

  • my_function 是函数名,函数体中只有一个 echo 命令用于输出 "Hello, World!"。

  • 调用时,只需写出函数名 my_function 即可执行该函数。

2. 函数接收参数

函数可以通过 $1, $2, $3, 等来接收参数,表示调用时传入的值。

bash复制代码greet() {
    echo "Hello, $1!"
}
​
greet "Alice"  # 输出:Hello, Alice!
greet "Bob"    # 输出:Hello, Bob!

解释

  • 函数 greet 接收一个参数 $1,并将其用于输出欢迎信息。

  • 你可以在函数调用时传递参数,$1 就是第一个传入的值。

3. 返回值

在 Shell 函数中,并不像其他编程语言那样直接通过 return 返回值,return 通常用于返回一个状态码(0 表示成功,非0 表示失败)。如果需要返回实际值,可以通过 echo 来实现。

bash复制代码add_numbers() {
    local sum=$(( $1 + $2 ))  # local 用于局部变量
    echo $sum
}
​
result=$(add_numbers 5 3)  # 调用函数并将返回值赋给变量
echo "Result: $result"      # 输出:Result: 8

解释

  • add_numbers 函数接收两个参数并计算它们的和。

  • echo 输出和,通过 $(...) 语法将其捕获并赋值给 result 变量。

4. 使用 return 返回状态码

return 语句用于返回一个状态码(通常是 0 或非零的整数),可以用来表示函数执行的成功或失败。

bash复制代码check_number() {
    if [ $1 -lt 0 ]; then
        return 1  # 返回非0,表示失败
    else
        return 0  # 返回0,表示成功
    fi
}
​
check_number -5
if [ $? -eq 0 ]; then
    echo "输入的是一个非负数"
else
    echo "输入的是一个负数"
fi

解释

  • check_number 函数检查传入的数字是否为负数。

  • 使用 return 返回一个状态码,$? 用于检查函数的返回值。如果是 0,表示函数执行成功;如果是非 0,表示失败。

5. 局部变量和全局变量

在 Shell 中,变量默认是全局的,可以在函数外部访问。在函数内部,若希望定义局部变量,可以使用 local 关键字。

bash复制代码function test_vars() {
    local var1="local variable"  # 局部变量
    var2="global variable"       # 全局变量
    echo "Inside function: $var1"
    echo "Inside function: $var2"
}
​
var2="This is global"
​
test_vars
echo "Outside function: $var2"  # 输出全局变量

解释

  • local 关键字用于定义局部变量 var1,该变量仅在函数内部有效。

  • var2 是全局变量,可以在函数外部访问。

6. 函数的递归调用

Shell 函数支持递归调用,即函数在其内部调用自己。注意要有结束条件,以避免无限递归。

bash复制代码factorial() {
    if [ $1 -le 1 ]; then
        echo 1
    else
        local result=$(( $1 * $(factorial $(( $1 - 1 ))) ))
        echo $result
    fi
}
​
result=$(factorial 5)
echo "5的阶乘是:$result"  # 输出:5的阶乘是:120

解释

  • factorial 函数计算一个数字的阶乘。

  • 当输入小于或等于 1 时,返回 1;否则,递归调用自己并计算阶乘。

7. 函数中的错误处理

在函数中进行错误处理时,可以通过检查命令的退出状态码或使用 set -e 来中止脚本。

bash复制代码divide() {
    if [ $2 -eq 0 ]; then
        echo "Error: Division by zero is not allowed!"
        return 1  # 返回错误码
    fi
    local result=$(( $1 / $2 ))
    echo $result
}
​
result=$(divide 10 0)
if [ $? -ne 0 ]; then
    echo "发生错误,不能除以零"
else
    echo "结果是:$result"
fi

解释

  • divide 函数检查是否发生了除零错误。

  • 如果第二个参数为 0,则返回错误码并输出错误信息。

8. 函数的默认参数

Shell 函数也可以设置默认参数,以防用户没有提供值。

bash复制代码greet() {
    local name="${1:-World}"  # 如果没有传递参数,则默认值为 "World"
    echo "Hello, $name!"
}
​
greet "Alice"  # 输出:Hello, Alice!
greet          # 输出:Hello, World!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值