Shell 编程

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

shell编程

在这里插入图片描述

  • 1.Shell 是一个用 C 语言编写的程序它是用户使用 Linux 的桥梁包裹在Linux内核的外面为用户和内核之间的交换提供一个接口
  • 2.Shell 也是一种解释器用户的命令都交给 Shell 解释执行
  • 3.Shell 脚本(shell script)是一种为 Shell 编写的脚本程序可以在Shell上解释运行
  • 4.Shell的种类(常用)
    • 1.Bourne Shell/usr/bin/sh或/bin/sh
    • 2.Bourne Again Shell/bin/bash

1.shell 脚本程序

在这里插入图片描述

  • 1.shell脚本的第一句需要指定它的解释器
    #!/bin/bash(默认解释器)
    
    • 1.#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序
    • 2.#!/bin/bash 也可以修改为 #!/bin/sh
    • 3.不指定也可以执行(默认采用/bin/bash)
  • 2.shell脚本的第二句可以写注释行
    #说明程序的功能开发者开发时间等
    
  • 3.shell脚本的程序体
    #顺序结构
    #分支结构(注意结束符then等)
    if..then..else...fi
    if...then...elif...then...else...fi
    case...esac
    #循环结构
    while...
    for...
    until...
    

2.启动shell程序的方式

  • 1.通过./shell脚本运行(需要先使用chmod命令把文件的权限设置成可读可执行)
    在这里插入图片描述
  • 2.通过bash/sh shell脚本运行
    在这里插入图片描述
  • 3.通过bash < shell脚本运行
    在这里插入图片描述
  • 4.通过source shell脚本运行
    在这里插入图片描述

3.shell 变量

1.环境变量

  • shell预定义变量用于设置系统运行环境该变量都是大写(例PATH)

2.位置变量

  • 命令 参数1 参数2 ...
  • $0表示第0个位置对应的变量

3.普通变量**

  • 1.命名只能使用英文字母数字和下划线首个字符不能以数字开头
  • 2.变量名中间不能有空格可以使用下划线 _
  • 3.不能使用标点符号
  • 4.不能使用bash里的关键字可用help命令查看保留关键字
  • 5.无类型可以直接赋值
  • 6.有read=两种赋值方式其中=两边不能有空格read可以同时给多个变量赋值enter键结束
  • 7.对该变量引用$ 变量名/序号$ {变量名/序号},后者一般用于对数组元素的引用
  • 8.变量名外面的花括号是可选的花括号是为了帮助解释器识别变量的边界
    your_name="tom"
    echo $your_name
    your_name="alibaba"
    echo $your_name
    

4.数组变量(一维)

  • 1.数组变量名=(元素1 元素2 元素3...);例Users=(Zsan lisi wangwu)
  • 2.输出指定下标数组元素echo ${ Users[0/1/2...] }
  • 3.输出数组中的全部元素echo $ {Users[*] }
  • 4.输出数组的长度echo $ { #Users[*]}
  • 5.数组赋值新的数组变量名=("${旧数组变量名[*]}")只能把旧数组的指定元素赋值给新数组的第一个元素

5.只读变量

  • 使用 readonly 命令可以将变量定义为只读变量只读变量的值不能被改变
    #!/bin/bash
    myUrl="https://www.google.com"
    readonly myUrl
    myUrl="https://www.runoob.com"
    
  • 运行脚本结果/bin/sh: NAME: This variable is read only.

6.特殊变量

  • 1.bash自动定义和赋值用户不能改变
  • 2.$$表示当前进程号
  • 3.$?表示前一个命令的退出状态
  • 4.$#表示命令的参数个数
  • 5.$0表示命令本身
  • 6.$ 1~$ n表示命令参数
  • 7.$*表示全部命令参数

7.删除变量

  • 使用 unset 命令可以删除变量
    unset variable_name
    
  • 变量被删除后不能再次使用unset 命令不能删除只读变量

4.shell 字符串

  • 字符串可以用单引号也可以用双引号也可以不用引号

1.单引号

str='this is a string'
  • 1.单引号里的任何字符都会原样输出单引号字符串中的变量是无效的
  • 2.单引号字串中不能出现单独一个的单引号对单引号使用转义符后也不行但可成对出现作为字符串拼接使用

2.双引号

your_name="runoob"
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
  • 1.结果Hello, I know you are "runoob"!
  • 2.双引号里可以有变量
  • 3.双引号里可以出现转义字符

3.拼接字符串

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1

# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2  $greeting_3
  • 1.结果hello, runoob ! hello, runoob !
    hello, runoob ! hello, ${your_name} !

4.获取字符串长度

string="abcd"
echo ${#string}   # 输出 4

# 变量为数组时${#string} 等价于 ${#string[0]}:
string="abcd"
echo ${#string[0]}   # 输出 4

5.提取子字符串

# 从字符串第 2 个字符开始截取 4 个字符
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo,第一个字符的索引值为 0

6.查找子字符串

# 查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
# 脚本中 ` 是反引号而不是单引号 '
string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4

5.shell 变量的输出

  • 1.echo $变量名1 $变量名2注意对变量的引用主要使用$且自动添加换行符
  • 2.printf 格式 变量 不会自动添加换行符\n
    在这里插入图片描述

1.echo 命令

1.显示普通字符串
echo "It is a test"
双引号可省略
echo It is a test
2.显示转义字符
echo "\"It is a test\""
双引号可省略
3.显示变量
  • read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
#!/bin/sh
read name 
echo "$name It is a test"
[root@www ~]# sh test.sh
OK                     #标准输入
OK It is a test        #输出
4.显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
OK!

It is a test
5.显示不换行
#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"
OK! It is a test
6.显示结果定向至文件
echo "It is a test" > myfile
7.原样输出字符串不进行转义或取变量(用单引号)
echo '$name\"'
$name\"
8.显示命令执行结果
echo `date`
注意 这里使用的是反引号 `, 而不是单引号 '
Thu Jul 24 10:08:46 CST 2014

2.printf 命令

转义字符说明
\a警告字符通常为ASCII的BEL字符
\b后退
\c抑制不显示输出结果中任何结尾的换行字符只在%b格式指示符控制下的参数字符串中有效而且任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符都被忽略
\f换页formfeed
\n换行
\r回车Carriage return
\t水平制表符
\v垂直制表符
\一个字面上的反斜杠字符
\ddd表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd表示1到3位的八进制值字符
printf  format-string  [arguments...]
  • format-string: 为格式控制字符串
  • arguments: 为参数列表
#!/bin/bash

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99
  • 1.%s %c %d %f 都是格式替代符
  • 2.%s 输出一个字符串
  • 3.%d 整型输出
  • 4.%c 输出一个字符
  • 5.%f 输出实数以小数形式输出
  • 6.%-10s 指一个宽度为 10 个字符- 表示左对齐没有则表示右对齐任何字符都会被显示在 10 个字符宽的字符内如果不足则自动以空格填充超过也会将内容全部显示出来
  • 7.%-4.2f 指格式化为小数其中 .2 指保留2位小数
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com

# format-string为双引号
printf "%d %s\n" 1 "abc"

# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"

# 没有引号也可以输出
printf %s abcdef

# 格式只指定了一个参数但多出的参数仍然会按照该格式输出format-string 被重用
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# 如果没有 arguments那么 %s 用空字符串代替%d 用 0 代替
printf "%s and %d \n"
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j  
and 0
$ printf "a string, no processing:<%s>\n" "A\nB"
a string, no processing:<A\nB>

$ printf "a string, no processing:<%b>\n" "A\nB"
a string, no processing:<A
B>

$ printf "www.runoob.com \a"
www.runoob.com $                  #不换行

3.test 命令

  • 1.shell中的 test 命令用于检查某个条件是否成立
  • 2.它可以进行数值、字符和文件三个方面的测试
  • 3.代码中的 [] 执行基本的算数运算
  • 4.test相当于中括号[]可以互换但是[]与内容需要用空格隔开
1.数值测试
参数说明
-eq等于则为真
-ne不等于则为真
-gt大于则为真
-ge大于等于则为真
-lt小于则为真
-le小于等于则为真
num1=100
num2=100
if test $[num1] -eq $[num2]
then
   echo '两个数相等'
else
   echo '两个数不相等'
fi
result=$[num1+num2] # 注意等号两边不能有空格
echo "result 为 $result"
2.字符串测试
参数说明
=等于则为真
!=不相等则为真
-z字符串 字符串的长度为零则为真
-n字符串 字符串的长度不为零则为真
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
   echo '两个字符串相等!'
else
   echo '两个字符串不相等!'
fi
3.文件测试
参数说明
-e 文件名如果文件存在则为真
-r 文件名如果文件存在且可读则为真
-w 文件名如果文件存在且可写则为真
-x 文件名如果文件存在且可执行则为真
-s 文件名如果文件存在且至少有一个字符则为真
-d 文件名如果文件存在且为目录则为真
-f 文件名如果文件存在且为普通文件则为真
-c 文件名如果文件存在且为字符型特殊文件则为真
-b 文件名如果文件存在且为块特殊文件则为真
  • shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来
  • 其优先级为 ! 最高 -a 次之 -o 最低
cd /bin
if test -e ./notFile -o -e ./bash
then
   echo '至少有一个文件存在!'
else
   echo '两个文件都不存在'
fi

6.shell 数组

  • 1.bash支持一维数组不支持多维数组并且没有限定数组的大小(初始化时不需要定义数组大小)
  • 2.数组元素的下标由 0 开始。获取数组中的元素要利用下标下标可以是整数或算术表达式其值应大于或等于 0

1.定义数组

  • 1.shell 中用括号来表示数组数组元素用空格符号分割开
  • 2.可以单独定义数组的每一个元素
  • 3.可以不使用连续的下标而且下标的范围没有限制
    数组名=(值1 值2 ... 值n)my_array=(A B "C" D)array_name=(
    		value0
    		value1
    		value2
    		value3
    	)
    或
    array_name[0]=value0
    array_name[1]=value1
    。。。
    array_name[n]=valuen
    

2.读取数组

${数组名[下标]}valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素
例
echo ${array_name[@]}
#!/bin/bash

my_array=(A B "C" D)

echo "第一个元素为: ${my_array[0]}"
echo "第二个元素为: ${my_array[1]}"
echo "第三个元素为: ${my_array[2]}"
echo "第四个元素为: ${my_array[3]}"
$ chmod +x test.sh 
$ ./test.sh
第一个元素为: A
第二个元素为: B
第三个元素为: C
第四个元素为: D

3.获取数组的长度

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

4.获取数组中的所有键/元素

#!/bin/bash

my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D

echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
$ chmod +x test.sh 
$ ./test.sh
数组的元素为: A B C D
数组的元素为: A B C D
  • 数组前加一个感叹号 ! 可以获取数组的所有键
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

echo "数组的键为: ${!site[*]}"
echo "数组的键为: ${!site[@]}"
数组的键为: google runoob taobao
数组的键为: google runoob taobao

5.关联数组

  • 1.Bash 支持关联数组可以使用任意的字符串、或者整数作为下标来访问数组元素
  • 2.关联数组使用 declare 命令来声明
  • 3.-A 选项用于声明一个关联数组
  • 4.关联数组的键是唯一的
    declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")declare -A site
    site["google"]="www.google.com"
    site["runoob"]="www.runoob.com"
    site["taobao"]="www.taobao.com"
    
    通过键来访问关联数组的元素
    echo ${site["runoob"]}
    
    www.runoob.com
    

7.shell 注释

1.单行注释

  • 1.以 # 开头的行就是注释会被解释器忽略
  • 2.通过每一行加一个 # 号设置多行注释
  • 3.注释的代码用一对花括号括起来定义成一个函数没有地方调用这个函数这块代码就不会执行达到了和注释一样的效果
    #--------------------------------------------
    # 这是一个注释
    # author菜鸟教程
    # sitewww.runoob.com
    # slogan学的不仅是技术更是梦想
    #--------------------------------------------
    ##### 用户配置区 开始 #####
    #
    #
    # 这里可以添加脚本描述信息
    #
    #
    ##### 用户配置区 结束  #####
    

2.多行注释

:<<EOF
注释内容...
注释内容...
注释内容...
EOF

或
:<<'
注释内容...
注释内容...
注释内容...
'
或
:<<!
注释内容...
注释内容...
注释内容...
!

8.shell 传递参数

  • 1.执行 shell 脚本时可以向脚本传递参数
  • 2.脚本内获取参数的格式为$n
  • 3.n 代表一个数字1 为执行脚本的第一个参数2 为执行脚本的第二个参数以此类推……
  • 4.$0 为执行的文件名包含文件路径)
    #!/bin/bash
    
    echo "shell 传递参数实例";
    echo "执行的文件名$0";
    echo "第一个参数为$1";
    echo "第二个参数为$2";
    echo "第三个参数为$3";
    
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    shell 传递参数实例
    执行的文件名./test.sh
    第一个参数为1
    第二个参数为2
    第三个参数为3
    

注意

  • $#传递到脚本的参数个数
  • $* 以一个单字符串显示所有向脚本传递的参数
  • $$脚本运行的当前进程ID号
  • $! 后台运行的最后一个进程的ID号
  • $@与$*相同但是使用时加引号并在引号中返回每个参数
  • $- 显示shell使用的当前选项与set命令功能相同
  • $?显示最后命令的退出状态。0表示没有错误其他任何值表明有错误
    #!/bin/bash
    
    echo "Shell 传递参数实例";
    echo "第一个参数为$1";
    
    echo "参数个数为$#";
    echo "传递的参数作为一个字符串显示$*";
    
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    Shell 传递参数实例
    第一个参数为1
    参数个数为3
    传递的参数作为一个字符串显示1 2 3
    
  • $*$@ 区别
  • 相同点都是引用所有参数。
  • 不同点只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3则 " * " 等价于 “1 2 3”传递了一个参数而 “@” 等价于 “1” “2” “3”传递了三个参数
    #!/bin/bash
    
    echo "-- \$* 演示 ---"
    for i in "$*"; do
        echo $i
    done
    
    echo "-- \$@ 演示 ---"
    for i in "$@"; do
    	    echo $i
    done
    
    $ chmod +x test.sh 
    $ ./test.sh 1 2 3
    -- $* 演示 ---
    1 2 3
    -- $@ 演示 ---
    1
    2
    3
    

9.shell 基本运算符

  • 原生bash不支持简单的数学运算但是可以通过其他命令来实现例awk 和 expr
  • expr 是一款表达式计算工具使用它能完成表达式的求值操作
    #!/bin/bash
    
    val=`expr 2 + 2`
    echo "两数之和为 : $val"
    #  结果 两数之和为 : 4
    
  • 注意使用的是反引号 而不是单引号 '
  • 表达式和运算符之间要有空格例2+2 是错误的必须写成 2 + 2
  • 完整的表达式要被 ``包含注意这个字符不是常用的单引号在 Esc 键下边

1.算术运算符

运算符说明
+加法
-减法
*乘法
/除法
%取余
=赋值
==相等用于比较两个数字相同则返回 true
!=不相等用于比较两个数字不相同则返回 true

注意

  • 1.条件表达式要放在方括号之间并且要有空格例: [$a==$b] 是错误的必须写成 [ $a == $b ]
  • 2.乘号*前边必须加反斜杠\才能实现乘法运算;
  • 3.MACshellexpr 语法是$((表达式))此处表达式中的 乘号*不需要转义符号 \
    #!/bin/bash
    
    a=10
    b=20
    
    val=`expr $a + $b` # 等价于 val = $(($a + $b))
    echo "a + b : $val"
    
    val=`expr $a - $b`
    echo "a - b : $val"
    
    val=`expr $a \* $b`
    echo "a * b : $val"
    
    val=`expr $b / $a`
    echo "b / a : $val"
    
    val=`expr $b % $a`
    echo "b % a : $val"
    
    if [ $a == $b ]
    then
       echo "a 等于 b"
    fi
    if [ $a != $b ]
    then
       echo "a 不等于 b"
    fi
    
    a + b : 30
    a - b : -10
    a * b : 200
    b / a : 2
    b % a : 0
    a 不等于 b
    

2.关系运算符

运算符说明
-eq检测两个数是否相等相等返回 true
-ne检测两个数是否不相等不相等返回 true
-gt检测左边的数是否大于右边的如果是则返回 true
-lt检测左边的数是否小于右边的如果是则返回 true
-ge检测左边的数是否大于等于右边的如果是则返回 true
-le检测左边的数是否小于等于右边的如果是则返回 true
  • 关系运算符只支持数字不支持字符串除非字符串的值是数字
    #!/bin/bash
    
    a=10
    b=20
    
    if [ $a -eq $b ]
    then
       echo "$a -eq $b : a 等于 b"
    else
       echo "$a -eq $b: a 不等于 b"
    fi
    if [ $a -ne $b ]
    then
       echo "$a -ne $b: a 不等于 b"
    else
       echo "$a -ne $b : a 等于 b"
    fi
    if [ $a -gt $b ]
    then
       echo "$a -gt $b: a 大于 b"
    else
       echo "$a -gt $b: a 不大于 b"
    fi
    if [ $a -lt $b ]
    then
       echo "$a -lt $b: a 小于 b"
    else
       echo "$a -lt $b: a 不小于 b"
    fi
    if [ $a -ge $b ]
    then
       echo "$a -ge $b: a 大于或等于 b"
    else
       echo "$a -ge $b: a 小于 b"
    fi
    if [ $a -le $b ]
    then
       echo "$a -le $b: a 小于或等于 b"
    else
       echo "$a -le $b: a 大于 b"
    fi
    
    10 -eq 20: a 不等于 b
    10 -ne 20: a 不等于 b
    10 -gt 20: a 不大于 b
    10 -lt 20: a 小于 b
    10 -ge 20: a 小于 b
    10 -le 20: a 小于或等于 b
    

3.布尔运算符

运算符说明
!非运算表达式为 true 则返回 false否则返回 true
-o或运算有一个表达式为 true 则返回 true
-a与运算两个表达式都为 true 才返回 true
#!/bin/bash

a=10
b=20

if [ $a != $b ]
then
  echo "$a != $b : a 不等于 b"
else
  echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
  echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
  echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
  echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
  echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
  echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
  echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
10 != 20 : a 不等于 b
10 小于 10020 大于 15 : 返回 true
10 小于 10020 大于 100 : 返回 true
10 小于 520 大于 100 : 返回 false

4.逻辑运算符

运算符说明
&&逻辑的 AND
||逻辑的 OR
#!/bin/bash

a=10
b=20

if [[ $a -lt 100 && $b -gt 100 ]]
then
  echo "返回 true"
else
  echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
  echo "返回 true"
else
  echo "返回 false"
fi
返回 false
返回 true

5.字符串运算符

运算符说明
=检测两个字符串是否相等相等返回 true
!=检测两个字符串是否不相等不相等返回 true
-z检测字符串长度是否为0为0返回 true
-n检测字符串长度是否不为 0不为 0 返回 true
$检测字符串是否不为空不为空返回 true
#!/bin/bash

a="abc"
b="efg"

if [ $a = $b ]
then
  echo "$a = $b : a 等于 b"
else
  echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
  echo "$a != $b : a 不等于 b"
else
  echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
  echo "-z $a : 字符串长度为 0"
else
  echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
  echo "-n $a : 字符串长度不为 0"
else
  echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
  echo "$a : 字符串不为空"
else
  echo "$a : 字符串为空"
fi
abc = efg: a 不等于 b
abc != efg : a 不等于 b
-z abc : 字符串长度不为 0
-n abc : 字符串长度不为 0
abc : 字符串不为空

6.文件测试运算符

操作符说明
-b file检测文件是否是块设备文件如果是则返回 true
-c file检测文件是否是字符设备文件如果是则返回 true
-d file检测文件是否是目录如果是则返回 true
-f file检测文件是否是普通文件既不是目录也不是设备文件如果是则返回 true
-g file检测文件是否设置了 SGID 位如果是则返回 true
-k file检测文件是否设置了粘着位(Sticky Bit)如果是则返回 true
-p file检测文件是否是有名管道如果是则返回 true
-u file检测文件是否设置了 SUID 位如果是则返回 true
-r file检测文件是否可读如果是则返回 true
-w file检测文件是否可写如果是则返回 true
-x file检测文件是否可执行如果是则返回 true
-s file检测文件是否为空文件大小是否大于0不为空返回 true
-e file检测文件包括目录是否存在如果是则返回 true
-S file判断某文件是否 socket
-L file检测文件是否存在并且是一个符号链接
#!/bin/bash

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
  echo "文件可读"
else
  echo "文件不可读"
fi
if [ -w $file ]
then
  echo "文件可写"
else
  echo "文件不可写"
fi
if [ -x $file ]
then
  echo "文件可执行"
else
  echo "文件不可执行"
fi
if [ -f $file ]
then
  echo "文件为普通文件"
else
  echo "文件为特殊文件"
fi
if [ -d $file ]
then
  echo "文件是个目录"
else
  echo "文件不是个目录"
fi
if [ -s $file ]
then
  echo "文件不为空"
else
  echo "文件为空"
fi
if [ -e $file ]
then
  echo "文件存在"
else
  echo "文件不存在"
fi
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在

10.算术运算

  • 1.$[表达式]
    在这里插入图片描述
  • 2.expr命令
    • expr的内容需要用`引用且中间内容必须空格隔开
      在这里插入图片描述
  • 3.let命令
    • 变量计算中不需要加上 $ 来表示变量需要将表达式用双引号引起来
      在这里插入图片描述
  • 4.((表达式))
    在这里插入图片描述

11.语句结构

1.分支结构if

#结构一不同行
if 表达式
then 命令表
[else 命令表]
fi
#结构二同行(if...then...else...fi在一行需要用分号隔开)
if 表达式;then 命令表;[else 命名表];fi
#结构三多层嵌套结构
if 表达式
then 命令表
[elif 表达式;then 命令表]
...
[elif 表达式;then 命令表]
[else 命令表]
fi

在这里插入图片描述

  • 1.if else 的 […] 判断语句中大于使用 -gt小于使用 -lt
  • 2.if else使用 ((…)) 作为判断语句大于和小于可以直接使用 > 和 <
  • 3.if else也可以使用test做判断语句
a=10
b=20

if [ $a == $b ]
then
  echo "a 等于 b"
elif [ $a -gt $b ]
then
  echo "a 大于 b"
elif [ $a -lt $b ]
then
  echo "a 小于 b"
else
  echo "没有符合的条件"
fi

if (( $a == $b ))
then
  echo "a 等于 b"
elif (( $a > $b ))
then
  echo "a 大于 b"
elif (( $a < $b ))
then
  echo "a 小于 b"
else
  echo "没有符合的条件"
fi

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
   echo '两个数字相等!'
else
   echo '两个数字不相等!'
fi

2.分支结构case

case 表达式 in
模式1 | [模式2] |...) 命令表1;;
模式3 | [模式4] |...) 命令表2;;
...
*) 命令表n;;
esac

在这里插入图片描述

  • 1.表达式判断条件通常是一个变量名称
  • 2.命令表可以是一个或多个命令
    1. 每一个模式必须以结尾
  • 4.每一个分支以;;结尾
  • 5.*表示不与以上任何一个模式匹配时运行此命名表
  • 6.每个 case 分支用开始用两个分号 ;; 表示 break即执行结束
  • 7.检测匹配的每一个模式一旦模式匹配则执行完匹配模式相应命令后不再继续其他模式
  • 8.如果无一匹配模式使用星号 * 捕获该值再执行后面的命令

3.选择结构select

select 变量 in 列表
do
命令表
done

在这里插入图片描述
在这里插入图片描述

  • 1.select选择结构可以简便生成具有编号的菜单
  • 2.select会给列表中的内容自动生成菜单标号下标从0开始
  • 3.selsect会根据输出的编号选择相应的内容并且赋值给相应的变量
  • 4.对应菜单编号可以使用case语言进行相应的操作

4.循环结构while

while((表达式))
do
命名表
done

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1.通常在无法确定循环的具体次数时使用while循环语句
  • 2.按<Ctrl-D>可以结束循环

5.for循环结构

for 变量 [in 列表]
do
命令表
donefor 变量 [in 列表]; do 命令表1; 命令表2... done;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1.for循环通常用于知道具体循环次数的情况
  • 2.dodone相当于大括号
  • 3.in 列表可以包含替换、字符串和文件名;若省略了in 列表则传递位置参数

6.until循环

until ((表达式))
do
命令表
done

在这里插入图片描述
在这里插入图片描述

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

7.break语句

  • 1.使用break结束循环跳出循环后将转到done语句后继续执行
  • 2.break 命令允许跳出所有循环终止执行后面的所有循环
#!/bin/bash
while :
do
   echo -n "输入 1 到 5 之间的数字:"
   read aNum
   case $aNum in
       1|2|3|4|5) echo "你输入的数字为 $aNum!"
       ;;
       *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
           break
       ;;
   esac
done

8.continue语句

  • 用来跳过本次循环即直接跳回到循环的开始位置(条件判断处)

12.shell 函数

[function] 函数名  ()
{
命令表
[return]
}
  • 1.shell函数类似于shell脚本里面存放了一系列命令
  • 2.使用一个函数之前必须创建该函数
  • 3.函数返回值在调用该函数后通过 $? 来获得
  • 4.函数名后面的括号里面没有参数参数是通过位置变量传递
  • 4.函数中使用exit命令则可以退出整个脚本
  • 6.如果函数退出就返回脚本中调用该函数的地方
  • 7.使用break语句可以中断函数的执行
  • 8.[]中的内容需要空格隔开[]test可以互换
  • 9.可以在脚本中运用其他文件中的函数source 文件名
  • 10.如果没有read可以使用位置参数传递即函数名 位置参数1 位置参数2 。。。
  • 11.注意$10 不能获取第十个参数获取第十个参数需要${10};当n>=10时需要使用${n}来获取参数
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

13.shell 输入/输出重定向

命令说明
command > file将输出重定向到 file
command < file将输入重定向到 file
command >> file将输出以追加的方式重定向到 file
n > file将文件描述符为 n 的文件重定向到 file
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file
n >& m将输出文件 m 和 n 合并
n <& m将输入文件 m 和 n 合并
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入
  • 注意文件描述符 0 通常是标准输入STDIN1 是标准输出STDOUT2 是标准错误输出STDERR

1.输出重定向

command1 > file1
  • 1.执行command1然后将输出的内容存入file1
  • 2.注意任何file1内的已经存在的内容将被新内容替代
  • 3.如果要将新内容添加在文件末尾请使用>>操作符

2.输入重定向

command1 < file1
$ wc -l users
      2 users
$ wc -l < users
      2     
command1 < infile > outfile # 执行command1从文件infile读取内容然后将输出写入到outfile

3.详解重定向

一般情况下每个 Unix/Linux 命令运行时都会打开三个文件

  • 1.标准输入文件(stdin)stdin的文件描述符为0Unix/Linux程序默认从stdin读取数据
  • 2.标准输出文件(stdout)stdout 的文件描述符为1Unix/Linux程序默认向stdout输出数据
  • 3.标准错误文件(stderr)stderr的文件描述符为2Unix/Linux程序会向stderr流中写入错误信息
  • 4.默认情况下command > filestdout 重定向到 filecommand < filestdin 重定向到 file
    # 将 stderr 重定向到 file
    $ command 2>file
    # 将 stderr 追加到 file 文件末尾
    $ command 2>>file
    # 将  stdout 和 stderr 合并后重定向到 file
    $ command > file 2>&1
    $ command >> file 2>&1
    # 将  stdin 重定向到 file1将 stdout 重定向到 file2
    $ command < file1 >file2
    

4./dev/null 文件

$ command > /dev/null
  • 1.执行某个命令但又不在屏幕上显示输出结果可以将输出重定向到 /dev/null
  • 2./dev/null 是一个特殊的文件写入到它的内容都会被丢弃
  • 3.从该文件读取内容那么什么也读不到但是 /dev/null 文件有用将命令的输出重定向到它会起到"禁止输出"的效果
  • 4.希望屏蔽 stdoutstderr可以这样写$ command > /dev/null 2>&1
  • 5.注意0 是标准输入STDIN1 是标准输出STDOUT2 是标准错误输出STDERR
  • 6.这里的 2> 之间不可以有空格2> 是一体的时候才表示错误输出

14.shell 文件包含

. filename   # 注意点号.和文件名中间有一空格source filename
test1.sh 代码如下

#!/bin/bash
url="http://www.baidu.com"

test2.sh 代码如下

#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "官网地址$url"

test2.sh 添加可执行权限并执行
其中被包含的文件 test1.sh 不需要可执行权限

$ chmod +x test2.sh 
$ ./test2.sh 
官网地址http://www.baidu.com
  • 1.shell 可以包含外部脚本可以方便封装一些公用的代码作为一个独立的文件
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: shell