文章目录
一、运算符1、算术运算符2、关系运算符3、布尔运算符4、逻辑运算符5、字符串运算符6、文件测试运算符二、字符串处理1、字符串切片2、基于模式取子串3、查找删除4、查找替换三、条件判断语法格式[] 和 [[]] 的区别:[] (test 命令)[[]] (扩展测试命令)详细对比总结四、流程控制if else 语法格式if else-if else 语法格式for循环while循环无限循环until 循环五、获取当前日期以及时间六、传递参数特殊参数$# 的含义$0 的含义常用命令find命令实例read命令实例Top

一、运算符

1、算术运算符

下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 -10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b 把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a ==$b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a !=$b ] 返回 true。

注意: 条件表达式要放在方括号之间,并且要有空格,例如: [​$a==$​b] 是错误的,必须写成 [ ​$a ==$​b ]

2、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq$b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne$b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt$b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt$b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge$b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le$b ] 返回 true。

3、布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
! 非运算,表达式为 true 则返回 false, [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o$b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a$b -gt 100 ] 返回 false。

4、逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明
&& 逻辑的 AND
|| 逻辑的 OR

5、字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a =$b ] 返回 false。
!= 检测两个字符串是否不相等,不相等返回 true。 [ $a !=$b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
$ 检测字符串是否不为空,不为空返回 true。 [ $a ] 返回 true。

6、文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

属性检测描述如下:

操作符 说明
-b file 检测文件是否是块设备文件,如果是,则返回 true。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。
-d file 检测文件是否是目录,如果是,则返回 true。
-e file 检测文件是否存在,如果是,则返回 true。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file 检测文件是否是有名管道,如果是,则返回 true。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。
-r file 检测文件是否可读,如果是,则返回 true。

其他检查符:


二、字符串处理

1、字符串切片

${变量:偏移量:截取长度}

--------------------------example
[192.168.2.230] - root@ubuntu20.04.5-template:/ root
$ MYPATH=' /usr/bin/wget'

[192.168.2.230] - root@ubuntu20.04.5-template:/root
$ echo ${MYPATH: 4:4}
/bin     			  #其会左向右从第四位向后取四位(字符串第一位为0)

[192.168.2.230] - root@ubuntu20.04.5-template:/ root
$ echo ${MYPATH: -4}  #这会右向左从末尾向前取四位,「-4和冒号之间要有一个空格」
Copied!

2、基于模式取子串

${var#*word}
其中word可以是指定的任意字符,自左而右,删除字符串开头至第一次出现word字符之间的所有字符。

${var##*word}
其中word可以是指定的任意字符,自左而右,删除字符串开头至最后一次出现word字符之间的所有字符。

${var%sword*}
其中word可以是指定的任意字符,自右而左,删除字符串尾部至第一次出现word字符之间的所有字符。

${var%%sword*}
其中word可以是指定的任意字符,自右而左,删除字符串尾部至最后一次出现word字符之间的所有字符
Copied!

3、查找删除

${var/匹配文本}
删除第一次匹配到的内容

${var//pattern}
删除所有匹配到的内容

${var/#pattern}
删除行首匹配到的内容

${var/%pattern}
删除行尾匹配到的内容
Copied!

4、查找替换

${var/匹配文本/替换文本}
替换第一次匹配到的内容

${var//匹配文本/替换文本}
替换所有匹配到的内容

${var/#匹配文本/替换文本}
行首匹配时替换行首

${var/%匹配文本/替换文本}
行尾匹配时替换行尾
Copied!

三、条件判断语法格式

特别说明

1)[ 亲亲,我两边都有空格,不空会被打死的喔~ ]

2)[[ 亲亲,我两边都有空格,不空会被打死的喔~ ]]

3)更多判断,man test查看,许多的参数都可用来进行条件判断

[] 和 [[]] 的区别:

[] (test 命令)

[] 是传统的测试条件的命令,也称为 test 命令。这种语法适用于POSIX标准的Shell,包括sh和bash。

[[]] (扩展测试命令)

[[]] 是Bash特有的扩展测试命令,提供了更强大的功能和更简洁的语法。

详细对比

总结

在实际编程中,建议在Bash脚本中尽量使用 [[]],除非需要兼容性考虑,这样可以充分利用其扩展功能和更清晰的语法。


四、流程控制

if else 语法格式

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi
Copied!

if else-if else 语法格式

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi
Copied!

if else 的 [...] 判断语句中大于使用 -gt,小于使用 -lt,其他用法请参照运算符

if [ "$a" -gt "$b" ]; then
    ...
fi
Copied!

如果使用((...)) 作为判断语句,就可以使用类c风格判断,大于和小于可以直接使用 > 和 <。

if (( a > b )); then
    ...
fi
Copied!

for循环

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
Copied!

举个栗子🌰

#!/bin/bash

for str in This is a string
do
    echo $str
done
Copied!

输出结果:

This
is
a
string
Copied!

要打印1 -> 10的数字,可以用以下格式

#!/bin/zsh

for i in {1..10}
do 
    echo "$i"
done
Copied!

或者以下类c风格

#!/bin/zsh

for ((i=1; i<11; i++))
do 
    echo "$i"
done
Copied!

while循环

while condition
do
    command
done
Copied!

举个栗子🌰

#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
Copied!

无限循环

无限循环语法格式:

while :
do
    command
done
Copied!

或者

while true
do
    command
done
Copied!

或者

for (( ; ; ))
Copied!

until 循环

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until 语法格式:

until condition
do
    command
done
Copied!

condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。


五、获取当前日期以及时间

在 Unix 或 Linux 系统中,date 命令用于显示或设置系统日期和时间。date 命令可以接受多种格式化字符串来指定输出的格式。

命令 date +%M 会返回当前时间中的“分钟”部分。例如,如果当前时间是 14:35,那么运行 date +%M 会输出 35

下面是一些常用的 date 格式化字符串及其含义:

所以,date +%M 的输出仅仅是当前时间的分钟部分。


六、传递参数

特殊参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为 $n,n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。

例如可以使用 $1、$2 等来引用传递给脚本的参数,其中$1表示第一个参数,$2 表示第二个参数,依此类推。

#!/bin/zsh脚本中,$#$0是特定的shell变量,用于脚本参数处理和信息获取。让我们详细解释它们的含义:

$# 的含义

$# 代表传递给脚本的参数数量。在脚本开头,有以下代码:

if [ $# -ne 1 ]; then
    echo "Usage: $0 <directory>"
    exit 1
fi
Copied!

这段代码的意思是:检查传递给脚本的参数数量是否不等于1。如果不是1个参数(即传递了0个参数或者多于1个参数),则输出使用说明并退出脚本。换句话说,$#用于确保脚本接收正好一个参数。

$0 的含义

$0 代表脚本自身的文件名(包含文件路径)。在脚本中同样的代码:

if [ $# -ne 1 ]; then
    echo "Usage: $0 <directory>"
    exit 1
fi
Copied!

在这个例子中,$0表示脚本文件的名称。假设脚本的文件名是rename_files.sh,那么当你执行这个脚本时,$0就会被替换为rename_files.sh。因此,输出的使用说明会是:

Usage: rename_files.sh <directory>
Copied!

常用命令

find命令

语法

find [路径] [匹配条件] [动作]
Copied!

参数说明 :
路径 是要查找的目录路径,可以是一个目录或文件名,也可以是多个路径,多个路径之间用空格分隔,如果未指定路径,则默认为当前目录。

expression 是可选参数,用于指定查找的条件,可以是文件名、文件类型、文件大小等等。
匹配条件 中可使用的选项有二三十个之多,以下列出最常用的部份:

动作: 可选的,用于对匹配到的文件执行操作,比如删除、复制等。

find 命令中用于时间的参数如下:

正数应该表示时间之前,负数表示时间之内。
例如:-mtime 0 表示查找今天修改过的文件,-mtime -7 表示查找一周以前修改过的文件。

关于时间 n 参数的说明:

实例

查找当前目录下名为 file.txt 的文件:

find . -name file.txt
Copied!

将当前目录及其子目录下所有文件后缀为 .c 的文件列出来:

find . -name "*.c"
Copied!

将当前目录及其子目录中的所有文件列出:

find . -type f
Copied!

如果后面的参数过多,可以用()括起来,但是注意使用 \ 转义符,以下命令的含义是找出当前目录以及子目录所有的.md和.txt文件

find . -type f \( -name "*.md" -o -name "*.txt" \)
Copied!

read命令

read 内部命令被用来从标准输入读取单行数据。这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据。

语法

read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Copied!

参数说明:

实例

1、简单读取

#!/bin/bash

#这里默认会换行  
echo "输入网站名: "  
#读取从键盘的输入  
read website  
echo "你输入的网站名是 $website"  
exit 0  #退出
Copied!

测试结果为:

输入网站名: 
www.runoob.com
你输入的网站名是 www.runoob.com
Copied!

2、-p 参数,允许在 read 命令行中直接指定一个提示。

#!/bin/bash

read -p "输入网站名:" website
echo "你输入的网站名是 $website" 
exit 0
Copied!

测试结果为:

输入网站名:www.runoob.com
你输入的网站名是 www.runoob.com
Copied!

3、-t 参数指定 read 命令等待输入的秒数,当计时满时,read命令返回一个非零退出状态。

#!/bin/bash

if read -t 5 -p "输入网站名:" website
then
    echo "你输入的网站名是 $website"
else
    echo "\n抱歉,你输入超时了。"
fi
exit 0
Copied!

执行程序不输入,等待 5 秒后:

输入网站名:
抱歉,你输入超时了
Copied!

4、除了输入时间计时,还可以使用 -n 参数设置 read 命令计数输入的字符。当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量。

#!/bin/bash

read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
      echo "fine ,continue";;
N | n)
      echo "ok,good bye";;
*)
     echo "error choice";;

esac
exit 0
Copied!

该例子使用了-n 选项,后接数值 1,指示 read 命令只要接受到一个字符就退出。只要按下一个字符进行回答,read 命令立即接受输入并将其传给变量,无需按回车键。

只接收 2 个输入就退出:

#!/bin/bash

read -n2 -p "请随便输入两个字符: " any
echo "\n您输入的两个字符是:$any"
exit 0
Copied!

执行程序输入两个字符:

请随便输入两个字符: 12
您输入的两个字符是:12
Copied!

5、-s 选项能够使 read 命令中输入的数据不显示在命令终端上(实际上,数据是显示的,只是 read 命令将文本颜色设置成与背景相同的颜色)。输入密码常用这个选项。

#!/bin/bash

read  -s  -p "请输入您的密码:" pass
echo "\n您输入的密码是 $pass"
exit 0
Copied!

执行程序输入密码后是不显示的:

请输入您的密码:
您输入的密码是 runoob
Copied!

6.读取文件
每次调用 read 命令都会读取文件中的 "一行" 文本。当文件没有可读的行时,read 命令将以非零状态退出。
通过什么样的方法将文件中的数据传给 read 呢?使用 cat 命令并通过管道将结果直接传送给包含 read 命令的 while 命令。
测试文件 test.txt 内容如下:

123
456
runoob
Copied!

测试代码:

#!/bin/bash
  
count=1    # 赋值语句,不加空格
cat test.txt | while read line      # cat 命令的输出作为read命令的输入,read读到>的值放在line中
do
   echo "Line $count:$line"
   count=$[ $count + 1 ]          # 注意中括号中的空格。
done
echo "finish"
exit 0
Copied!

执行结果为:

Line 1:123
Line 2:456
Line 3:runoob
finish
Copied!

使用 -e 参数,以下实例输入字符 a 后按下 Tab 键就会输出相关的文件名(该目录存在的):

$ read -e -p "输入文件名:" str 
输入文件名:a
a.out    a.py     a.pyc    abc.txt  
输入文件名:a
Copied!
要做一个有swag的人