Linux中shell脚本详解

x33g5p2x  于2022-05-05 转载在 Linux  
字(7.4k)|赞(0)|评价(0)|浏览(1058)

Shell:一般我们是用图形界面和命令去控制计算机,真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),由于安全、复杂、繁琐等原因,用户不能直接接触内核,需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核,内核和用户之间就多了一层“中间代理”,Shell 其实就是一种脚本语言,也是一个可以用来连接内核和用户的软件,我们编写完源码后不用编译,直接运行源码即可。

常用的Shell:bash由 GNU 组织开发,sh 是 UNIX 上的标准 shell,是第一个流行的 Shell,bash保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。现在sh 已经基本被 bash 代替,bash是sh的扩展补充,但是也有些是不兼容的,大多数情况下区别不大,特殊场景可以使用 bash 代替 sh。

在ubuntu下,上图是我们打开的终端,这里输入的命令就是我们shell的命令,一般$表示的是普通用户,而#表示的是超级用户(root)

1、第一个脚本程序:

在终端创建一个.sh文件,vi test.sh

第一行,#!是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,用的是哪种shell,后面的/bin/bash就是指明了解释器的具体位置。
第二行#是注释行,用来解释说明,当然#!是特殊的,不在此类。 第三行在是终端输出 hello,is me!

执行shell脚本:

./test.sh: ./表示当前目录,执行./test.sh会说明权限不够,不能执行。需要改变文件的权限:chmod 777 test.sh,就能执行

. ./test.sh: 在不想改变权限的时候,测试脚本是不是能够正常使用。. 临时增加权限。

2、shell获取字符串长度:

  1. #!/bin/bash
  2. #获取字符串长度
  3. str="123456"
  4. echo "${#str}"

结果:

3、shell变量:

在bash shell中,每一个变量的值都是字符串, 当然也可以用declare 关键字显式定义变量的类型,在赋值的时候等号两边不能有空格,如:str=1 ,str=‘1’ ,str=“1”,变量名必须有字母、下划线、数字组成,开头必须字母或者下划线,不能用shell。

  • 局部变量:shell也有自定义函数,函数里面的变量为局部变量,但是它也是相当于全局变量,函数中的变量,在函数外调用也是可以的,如果要仅限函数使用,需要在函数变量前加个关键字:local
  • 全局变量:每打开一个终端就是一个shell会话,在这个shell会话(终端)定义的变量就是全局变量,它在这个shell会话有效,当你打开另一个终端就是另一个shell会话,这个变量在另一个终端就失效了。
  • 环境变量:在全局变量前加 export ,如:export a=1 那么这个变量就是环境变量了。创建这个变量的shell成为父shell,这个shell中,在创建一个shell叫做子shell,环境变量可以由父shell往下一级一级传,而不能逆转往上传递。当shell会话销毁时,这个环境变量也会随之销毁。想要永久保存就得环境变量写到启动文件中去。

4、引用shell变量

使用shell变量在变量前面加一个$,而标准的是 &{},目的是在一长串字符中可以识别出这个变量,而不会引起误会,如下:

  1. #!/bin/bash
  2. #引用shell变量
  3. str="abc"
  4. echo "$str"
  5. echo "the str vaile is: $str1"
  6. #后面增加一个1,就不能正确的识别变量
  7. echo "the str vaile is: ${str}1"
  8. #所以我们引用变量,最好统一用 ${} 的形式

结果:

5、shell变量的赋值、修改、删除:

a)、shell变量的赋值

  1. #!/bin/bash
  2. #变量的赋值
  3. n=1
  4. v1=${n}
  5. v2='${n}'
  6. v3="${n}"
  7. echo "${v1}"
  8. echo "${v2}"
  9. echo "${v3}"

可以从结果看出不加引号和加双引号的结果是相同的,而单引号是原样输出变量后面赋值的内容。

b、shell变量的修改、删除:

  1. #!/bin/bash
  2. #变量值的修改
  3. a=1
  4. echo "a: ${a}"
  5. a=2
  6. echo "a: ${a}"
  7. #只读变量是不可以修改的,在变量前加readonly,就是只读变量
  8. c=1
  9. echo "c: ${c}"
  10. readonly c
  11. c=2
  12. echo "c: ${c}"
  13. #只要在变量前面加一个 unset,如: unset a 就可以删除变量。
  14. unset a
  15. echo "a: ${a}"

5、shell特殊变量:

$0当前脚本的文件名或者解释器。
$n(n≥1)传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。当被双引号" "包含时,$@ 与 ∗ 稍 有 不 同 , * 稍有不同,∗稍有不同,*的所有参数是一个数据,而$@一个参数就是一份数据
$?上个命令的退出状态,或函数的返回值
$$当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。

**脚本:**如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如${10}${11}

  1. #!/bin/bash
  2. #shell特殊变量
  3. #$n: $0表示本脚本,$1表示输入的第一个参数:11,$2表示输入的第一个参数:22
  4. echo "$ 0: $0"
  5. echo "a: $1"
  6. echo "b: $2"
  7. #$*: 输入的参数 11 22
  8. echo "$ *: $*"
  9. #$@: 输入的参数 11 22
  10. echo "$ @: $@"
  11. #$$: shell进程id
  12. echo "$ $: $$"
  13. #$#: 参数个数 2
  14. echo "$ #: $#"

函数:如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如 ${10}${11}

  1. #!/bin/bash
  2. #shell特殊变量
  3. #$n: $0表示本脚本,$1表示输入的第一个参数:11,$2表示输入的第一个参数:22
  4. function temp(){
  5. echo "$ 0: $0"
  6. echo "a: $1"
  7. echo "b: $2"
  8. #$*: 输入的参数 11 22
  9. echo "$ *: $*"
  10. #$@: 输入的参数 11 22
  11. echo "$ @: $@"
  12. #$$: shell进程id
  13. echo "$ $: $$"
  14. #$#: 参数个数 2
  15. echo "$ #: $#"
  16. }
  17. temp 11 12

$?:上一个命令的退出状态,或者返回值:

  1. #!/bin/bash
  2. if [ $1 == 11 ]
  3. then
  4. return 0
  5. else
  6. return 1
  7. fi

$?在shell函数中的应用:

  1. #!/bin/bash
  2. function temp(){
  3. return $1
  4. }
  5. temp 3
  6. #$?: 这里是函数的返回值
  7. echo "$ ?: $?"

6、shell中字符串的拼接:

  1. #!/bin/bash
  2. #shell字符串的拼接
  3. n1=ab
  4. n2=cd
  5. temp1=${n1}${n2} #中间不能有空格
  6. temp2="${n1}${n2}"
  7. temp3="${n1}cdefg"
  8. echo "${temp1}"
  9. echo "${temp2}"
  10. echo "${temp3}"

7、字符串的截取

  • ${string: start :length}:字符串从左边start开始的位置截取length个字符,如果没有length,就从左边start开始到结束
  • ${string: 0-start :length}:字符串从右边start开始的位置截取length个字符,如果没有length,就从右边数start开始到结束
  • ${string#*chars}:字符串从边开始的第一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string##*chars}:字符串从边开始的最后一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string%*chars}:字符串从边边开始的第一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string%%*chars}:字符串从边开始的最后一个chars开始的位置截取到边结束,chars本身不在截取范围内
  1. #!/bin/bash
  2. #shell截取字符串
  3. str=http//:baidu.com/.c
  4. echo "length: ${str:7:5}" # baidu
  5. echo "no length: ${str:7}" # baidu.com/.c
  6. echo "length: ${str:0-7:5}" # .com/
  7. echo "no length: ${str:0-7}" # .com/.c
  8. echo "#: ${str#*/}" # /:baidu.com/.c
  9. echo "##: ${str##*/}" # .c
  10. echo "%: ${str%/*}" # http//:baidu.com
  11. echo "%%: ${str%%/*}" # http

8、shell中的数组:

bash shell 中只支持一维,而不支持二维,定义的形式:array=(n1 n2 n3) ,数组名等号两边不能有空格,数组变量的值用空格隔开表示不同的值,一个数组变量的值可以用数字或者字符串不同的形式组成:array=(1 2 ab) 。

Shell 数组的长度不是固定的,定义之后还可以增加元素,如:array[3]=cd ;就在最后增加了一个元素。

也不用逐个赋值;如:array=([2]=ab);但他的长度是1

调用数组:

  • ${array[0]}
  • a=${array[0]}
  • ${array[*]} //表示数组的所有元素
  • ${array[@]} //表示数组的所有元素
  1. #!/bin/bash
  2. #shell中的数组
  3. array=( 1 2 ab)
  4. n=${array} #array中的第一个元素赋值给n
  5. echo "array[0]: ${array[0]}"
  6. echo "array[*]: ${array[*]}"
  7. echo "n[*]: ${n[*]}"
  8. array[5]=cd
  9. echo "array[5]: ${array[5]}"
  10. echo "array[@]: ${array[@]}"

获取shell数组的元素个数或者shell数组里字符串的长度:${#array[*]}、${#array[@]}、${#array[4]}

  1. #!/bin/bash
  2. #shell中的数组
  3. array=( 1 2 abc)
  4. echo "#array[*] ${#array[*]}"
  5. array[4]=12345
  6. echo "#array[@] ${#array[*]}" #这边多加了一个元素就是4
  7. echo "#array[4] ${#array[4]}" #这边是计算array[4]中字符串的长度

数组的拼接:利用${array[*]}、${array[@]}

  1. #!/bin/bash
  2. #shell中的数组的拼接
  3. array1=( 1 2 abc)
  4. array2=(cd ef)
  5. array3=(${array1[@]} ${array2[@]})
  6. echo "array3: ${array3[@]}"
  7. echo "array3 length: ${#array3[@]}"

shell数组元素的删除:unset

  1. #!/bin/bash
  2. #shell中的数组
  3. array1=(1 2 abc)
  4. array2=(1 2 abc)
  5. unset array1[2] #删除array1数组中的一个元素abc
  6. echo "array1[*]: ${array1[*]}"
  7. unset array2 #删除整个数组array2
  8. echo "array2[*]: ${array2[*]}"

9、shell中条件判断if:

a)、if单分支:

-eq 等于,如:if [ “$a” -eq “$b” ]

-ne 不等于,如:if [ “$a” -ne “$b” ]

-gt 大于,如:if [ “$a” -gt “$b” ]

-ge 大于等于,如:if [ “$a” -ge “$b” ]

-lt 小于,如:if [ “$a” -lt “$b” ]

-le 小于等于,如:if [ “$a” -le “$b” ]

  1. #!/bin/bash
  2. #shell中if:
  3. #if单分支第一中形式:if []
  4. if [ 1 -eq 1 ] #[]里面的数据和中括号必须一个空格
  5. then
  6. echo "first if:真"
  7. fi
  8. #if单分支第二中形式:if []; then
  9. if [ 1 -eq 1 ]; then #then和if写在同一行必须要用;
  10. echo "second if:真"
  11. fi
  12. #if单分支第三中形式:if (())
  13. if ((1==1))
  14. then
  15. echo "third if:真"
  16. fi

b、双分支if:

  1. #!/bin/bash
  2. #shell中if:
  3. #if双分支
  4. if ((1==0)) #判断1和o是不是相等
  5. then
  6. echo "我是真的"
  7. else
  8. echo "我是假的"
  9. fi
  10. #................................
  11. if [ 1 -eq 0 ] #判断1和o是不是相等,
  12. then
  13. echo "我是真的"
  14. else
  15. echo "我是假的"
  16. fi

3、iif多分支:

  1. #!/bin/bash
  2. #shell中if:
  3. #if多分支
  4. if ((1==0)) #判断1和o是不是相等
  5. then
  6. echo "1=0;是真的"
  7. elif ((1>0))
  8. then
  9. echo "1>0;是真的"
  10. else
  11. echo "1>0;是假的"
  12. fi
  13. #..............................
  14. if [ 1 -eq 0 ] #判断1和o是不是相等
  15. then
  16. echo "1=0;是真的"
  17. elif [ 1 -gt 0 ]
  18. then
  19. echo "1>0;是真的"
  20. else
  21. echo "1>0;是假的"
  22. fi

10、shell中的 case语句:

  1. #!/bin/bash
  2. #shell中的case
  3. read VAILE #在屏幕中输入一个数,1或者2,如果不是这两个数就代表其他;即 *),
  4. case ${VAILE} in
  5. "1")
  6. echo "我是1"
  7. ;;
  8. "2")
  9. echo "我是2"
  10. ;;
  11. *)
  12. echo "我不是1,也不是2"
  13. ;;
  14. esac

11、shell中的 for循环:

a)、for循环形式1:

  1. #!/bin/bash
  2. #shell中的 for
  3. for n in 1 3 5 #n是我们自定义的变量,in后面三个数就是循环3次,每次的值从第一个数的值开始
  4. do
  5. echo "我是n,我的值是:${n}"
  6. done

b)、for循环形式2:与c语言的形式类似

  1. #!/bin/bash
  2. #shell中的 for
  3. for ((n=0;n<3;n++))
  4. do
  5. echo "我是n,我的值是:${n}"
  6. done

12、shell中的 while循环:

  1. #!/bin/bash
  2. #shell中的 while
  3. n=0
  4. while [ ${n} -lt 2 ] #n<2;就循环,否则退出循环
  5. do
  6. n=$((${n}+1))
  7. echo "我是n,我的值是:${n}"
  8. done
  9. echo "我退出循环了"

13、shell中的 until循环:

  1. #!/bin/bash
  2. #shell中的 until
  3. n=-2
  4. until ((n>1)) #不满足条件就循环,满足条件则退出循环
  5. do
  6. n=$((${n}+1))
  7. echo "我是n,我的值是:${n}"
  8. done
  9. echo "我退出循环了"

14、shell循环中的break和continue:

  1. #!/bin/bash
  2. #shell中的 break/continue
  3. n=0
  4. while ((n<6)) #n<6;就循环,否则退出循环
  5. do
  6. n=$((${n}+1))
  7. if ((n==2))
  8. then
  9. echo "我应该打印2,但我continue了"
  10. continue
  11. fi
  12. if ((n==5))
  13. then
  14. echo "n循环6次,应该等于6,但我break了,我现在的值是:${n}"
  15. break
  16. fi
  17. echo "我是n,我的值是:${n}"
  18. done
  19. echo "我退出循环了"

15、shell中的函数:

function 函数名(){

}

  1. #!/bin/bash
  2. #shell中的函数
  3. function fun(){
  4. if(($1 > 1)); then
  5. echo "条件成立"
  6. fi
  7. if(($2 > 1)); then
  8. echo "条件成立"
  9. else
  10. echo "条件不成立"
  11. fi
  12. }
  13. fun 2 1 #这边传参数给fun()函数

相关文章