shell语言详解

Shell

变量tips

  • 定义变量时,等号周围不能有空格;

  • 定义变量中不能有空格;

  • 变量使用时,前面要加$;

  • 建议使用变量时将变量用花括号括起来;

  • 只读变量可以在变量前加readonly

    • #!/bin/bash
      myUrl="https://www.google.com"
      readonly myUrl
      
  • 删除变量可以使用unset,变量被删除后不能再次使用,unset不能删除只读变量;

字符串

  • 单引号字符串里任何字符都会原样输出,单引号字符串中变量是无效的;

  • 单引号字符串中不能出现单独的一个单引号,加转义字符也不行;

  • 双引号里可以有变量;

  • 双引号里可以出现转义字符;

  • 获取字符串长度string="abcd" echo ${#string},即表示变量的$符号后加一个#

  • 提取子字符串

    • string="runoob is a great site"
      echo ${string:1:4} # 输出 unoo
      

数组

  • 数组元素间用空格分割;
  • 取数组元素${数组名[下标]}
  • 取数组所有元素${数组名[@]}
  • 获取数组长度${#数组名[@]}

注释

  • #表示注释;

  • #多行注释
    :<<EOF
    注释内容。。。
    EOF
    ##或者
    :<<'
    ...
    '
    ##或者
    :<<!
    ...
    !
    

传参

  • 向脚本传递参数,脚本内使用的格式为$n,n代表第几个参数,$1表示第一个参数;

  • $0表示执行的文件名,包含文件路径;

  • $#表示传递到脚本参数的个数;

  • $*以一个单字符串的形式显示所有向脚本传递的参数;

  • $$脚本运行的当前进程的ID号;

  • $!后台运行的最后一个进程的ID号;

  • $@$*相同,但是使用时加引号,并在引号中返回每个参数(不是单字符串了)

    • 使用"$@"则返回"$1" "$2" … "$n"
  • $-显示Shell使用的当前选项;

  • $?显示最后命令的退出状态;

运算

  • 要进行数学运算,需要使用斜点val=expr 2 + 2

  • 表达式和运算符之间要有空格,这点要区分变量赋值,变量赋值等号周围不能加空格;

  • 方括号[ ]等价与test,方括号周边要加空格;

  • 乘号前面必须要加反斜杠[ $a \* $b ]

  • 布尔运算:

    • !取非;
    • -o取或;
    • -a取与;
  • 逻辑运算:

    • &&逻辑与;
    • ||逻辑或;
  • 字符串运算:

    • =检查字符串相等;
    • !=检查字符串不等;
    • -z检查字符串长度是否为0,为0返回true;
    • -n检查字符串是否不为0,不为0返回true;
    • $检测字符串是否为空,不为空返回true;
  • 文件测试:

    • -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判断文件是否是socket;
    • -L检测文件是否存在合并是一个符号链接;

命令行展开

{}会在脚本中展开表达式,..表示递归,第三位表示步长

如:

{1..5}展开就是1 2 3 4 5

{1..5..2}展开就是1 3 5

别名

alias为某命令产生一个别名

unalias取消这个别名

历史命令

history会展示之前的历史命令,命令前有编号

{!num}运行history中对应数字的命令

{!!}运行上一条命令

快捷键

^表示CTRL

^A移动光标到行首

^E移动光标到行尾

^U剪切这一行

^K剪切光标之后的所有内容

^Y粘贴之前剪切的内容

^L等同于clear,清屏

^D退出当前程序,正常退出

^C退出当前程序,非正常退出

^Z暂停(挂起)当前程序,并放入后台

^S暂停屏幕输出

^Q恢复屏幕输出

^R在历史命令中搜索

正则表达式

元字符

基本正则字符

^:行首

$:行尾

[]:选字,如[abc]则为abc中的任意一个,还可以范围匹配[a-c],表示abc

*:任意字符,包括空,出现任意次

.:任意一个字符(非换行),有且只有一个

扩展正则字符

():分组,被其包裹的部分是一个整体,并获取这个匹配,可以在后面使用

{}:匹配前一个分组的某些次数

?:前一个字符的零次或一次,若前面是一个限制符时,匹配模式是非贪婪的(即尽可能匹配少的字符)

+:前面一个字符的一次及以上

|:表示或者,同时过滤多个字符串

\:转义字符(escape char),跟在其后的,表示其字符本身含义,而不是其正则含义,或者将普通字符转义为特殊字符

\b:匹配一个单词边界,也就是单词和空格间的位置

\B:匹配非单词边界

\cx:匹配由x指明的控制字符,如\cM匹配^M,x必须是字母

\d:匹配一个数字

\D:匹配一个非数字

\f:匹配一个换页符,等价于\x0c\cL

\n:匹配一个换行符,等价于\x0a\cJ

\r:匹配一个回车符,等价于\x0d\cM

\s:匹配一个空白字符,包括空格,制表,换页等

\S:匹配任何非空白符

\t:匹配一个制表符

\v:匹配一个垂直制表符

\w:匹配字母,数字,下划线(如c语言中合法的变量名)

\W:匹配非字母,数字,下划线

\xn:匹配n,其中n是16进制转义值,必须为两个字符

\num:匹配num,其中num是一个正整数,是对所获取的匹配的引用,如(.)\1匹配两个连续的相同字符

\n:n是一个数字,标识一个8进制转义值或一个向后引用。如果\n之前有至少n个获取的子表达式,则n为向后引用,否则,如果n为八进制数字,则n为一个八进制转义值

\nm:n,m都是一个数字,标识一个八进制转义值,或者一个向后引用,最多到99

\nml:匹配八进制数字,如n0-3ml0-7,则匹配八进制转义值nml

\un:匹配n,其中n是四个16进制数字表示的Unicode字符,如\u00A9表示

组合字符

^$:表示空行(啥也没有)

.*:匹配至少一个的所有内容,没有空

^.*:匹配任意多个字符开头

.*$:匹配任意多个字符结尾

[^abc]:反选,匹配非abc的任意字符

a{n, m}:匹配前一个分组的至少n次,至多m次,如a{1, 3},匹配 aaaaaa

a{n, }:匹配前一个分组的至少n次,至多不限

a{, m}:匹配前一个分组的至多m次,至少不限

a{n}:匹配前一个分组正好n次

(?:pattern):匹配,但不获取这个匹配结果

(?=pattern):正向肯定预查,在任何匹配pattern的字符串处匹配查找字符串

(?!pattern):正向否定预查,在任何不匹配pattern的字符串处匹配查找字符串

(?<=pattern):反向肯定预查,在任何匹配pattern的字符串处匹配查找字符串,方向和正向相反

(?<!pattern):反向否定预查,在任何不匹配pattern的字符串处匹配查找字符串,方向和正向相反

[]+:方括号内的内容的一次或多次

<>:定位单词的左侧和右侧

字符簇

[[:alpha:]]:任何字母

[[:digit:]]:任何数字

[[:alnum:]]:任何字母和数字

[[:space:]]:任何空白字符

[[:upper:]]:任何大写字母

[[:lower:]]:任何小写字母

[[:punct:]]:任何标点符号

[[:xdigit:]]:任何16进制的数字

优先级

相同优先级的从左到右运算,不同优先级的先高后低

运算符 描述
\ 转义符
(), (?:), (?=), [] 圆括号与方括号
*, +, ?, {n}, {n,},{n,m},{,m} 限定符
^, $, \任何元字符、任何字符 定位点和序列
` `

修饰符

i:忽略大小写

g:全局匹配

m:多行匹配

s.中包含换行\n


shell语言详解
https://yill-z.github.io/2025/01/01/shell/
作者
Yill Zhang
发布于
2025年1月1日
许可协议