• 【shell 特殊字符】


    井号(#)

    注释

    • 以一个#开头的行 (#!是例外) 是注释行
    • 注释也可以出现在一个命令语句的后面
    • 注释行前面也可以有空白字符
    • 在echo命令给出的一个转义的#字符并不会开始一个注释
    # 输出:这里
    echo 这里 #是一个注释
    
    # 输出:这里#不是一个注释
    echo 这里#不是一个注释
    
    # 输出:这里 #不是一个注释
    echo 这里 \#不是一个注释
    
    # 输出:这里 #不是一个注释
    echo "这里 #不是一个注释"
    
    # 输出:这里 #不是一个注释
    echo '这里 #不是一个注释'
    
    # 我是注释
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    分号(;)

    命令分割符

    • 分割符允许在同一行里有两个或更多的命令
    • ”;” 有时需要转义
    echo 123;echo 456
    : """
    输出:
    123
    456
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    双分号(;;)

    case语句分支的结束符

    case "${VAR}" in 
        abc)
            echo "\${VAR} = 123"
            ;;
        xyz) 
            echo "\${VAR} = 456"
            ;;
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    点(.)

    等同于source

    . ~/.bash_profile
    # 等效于
    source ~/.bash_profile
    
    • 1
    • 2
    • 3

    作为一个文件名的组成部分

    • 当点(.)以一个文件名为前缀时,起作用使该文件变成了隐藏文件
    • 作为目录名时,单个点(.)表示当前目录,两个点(…)表示上一级目录
    # 不显示隐藏文件
    ls -l ~
    # 显示隐藏文件
    ls -la ~
    
    cd .
    pwd # 输出:/root
    cd ..
    pwd # 输出:/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符匹配

    • 作为正则表达式的一部分,匹配字符时,单点(.)表示匹配任意一个字符
    ls | grep 'l.b'
    : """
    输出:
    lib
    lib64
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    双引号(")

    字符串引用(部分引用)

    VAR="Hello $USER"
    echo ${VAR} #输出:Hello root
    
    • 1
    • 2

    单引号(')

    字符串引用(完全引用)

    VAR='Hello $USER'
    echo ${VAR} # 输出:Hello $USER
    
    • 1
    • 2

    逗号(,)

    逗号操作符

    • 用于连接一连串的数学表达式。这一串的数学表达式每一个都被求值,但只有最后一个被返回
    let "a=((b=1,15/3))"
    echo $a # 输出5
    echo $b # 输出1
    
    • 1
    • 2
    • 3

    后斜杠(\)

    转义符

    • 用于单个字符的引用机制
    • \X "转义"字符为X.它有"引用"X的作用,也等同于直接在单引号里的’X’
    • \符也可以用于引用双引号(")和单引号('),这时双引号和单引号就表示普通的字符,而不是表示引用了
    # 下面四种等效
    echo \x # 输出:x
    echo x # 输出:x
    echo "x" # 输出:x
    echo 'x' # 输出:x
    
    # "和'转义
    echo \'  # 输出:'
    echo \"  # 输出:"
    echo "\"" # 输出:"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    前斜杠(/)

    文件路径的分隔符

    • 分隔一个文件路径的各个部分
    mkdir -p /data/pgdata
    
    • 1

    除法

    expr 15 / 3 # 输出:5
    
    • 1

    斜引号(`)

    命令替换

    • 引住的命令(command)执行结果能赋值给一个变量
    echo `ls -lh`
    
    • 1

    冒号(:)

    空命令

    • 空操作(即什么操作也不做)
    • 它一般被认为是和shell的内建命令true是一样的
    • 它的退出状态码是真(即0)
    :
    echo $? # 输出:0
    
    if [ : ]; then echo '123';fi
    
    • 1
    • 2
    • 3
    • 4

    分隔符

    • 在必须要有两元操作的地方作为一个分隔符
    : ${username=`whoami`}
    
    • 1
    • 代码块注释,但是会检测注释部分的正确性,否则会报错
    : <<EOF
    echo 1  # 这里是注释,但是一定是能执行的代码,不能执行的命令放这会报错
    echo 2  # 这里是注释,但是一定是能执行的代码,不能执行的命令放这会报错
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 域分隔符
    echo $PATH
    : """
    输出:
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/pgsql/bin:/root/bin:/root/bin:/root/bin
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 在参数替换中为字符串变量赋值
    # 多用来检测环境变量,未定义会报错
    : ${HOSTNAME?} ${USER?} ${MAIL?}
    
    • 1
    • 2

    变量扩展/子串替换

    VAR=123456789
    echo ${VAR:6} # 输出:789
    echo ${VAR:6:2} # 输出:78
    
    • 1
    • 2
    • 3

    和重定向符同时使用

    • 和重定向操作符(>)连用, 可以把一个文件的长度截短为零,文件的权限不变
    • 如果文件不存在,则会创建一个新文件
    # 下面作用相同
    # 但是,用NULL(:)操作符不会产生一个新的进程,因为NULL操作符是内建的
    : > tmp
    cat /dev/null > tmp
    echo '' > tmp
    
    • 1
    • 2
    • 3
    • 4
    • 5

    感叹号(!)

    取反

    • 它能改相等符( = )为不等符( != )
    # 输出:true
    if [ "1" != "2" ];then echo "true" ;fi
    
    • 1
    • 2

    间接引用

    • 在不同的环境里,感叹号也可以出现在间接变量引用
    a=b
    b=3
    eval echo \$$a # 输出:3
    echo ${!a} # 输出:3
    
    • 1
    • 2
    • 3
    • 4

    历史命令

    • 在命令行中,感叹号(!)调用属于历史命令机制的调用
    • 在一个脚本里,命令历史机制是被禁止的
    !!
    
    • 1

    星号(*)

    通配符

    • 星号(*)字符在用于匹配文件名扩展的一个通配符
    • 它自动匹配给定的目录下的每一个文件
    echo *
    
    • 1

    模式匹配

    • 星号(*)也用于正则表达式中匹配任意字符
    cd / && ll | grep 'usr*'
    
    • 1

    算数操作符

    • 星号(*)表示乘法运算符
    • 两个星号(**)表示求幂运算符
    let b="((a=2*3,2**3))"
    echo $a $b  # 输出:6 8
    expr 2 \* 3 # 输出:6
    echo $((2 * 3)) # 输出:6
    echo $((2 ** 3)) # 输出:8
    echo $[2 * 3] # 输出:6
    echo $[2 ** 3] # 输出:8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    问号(?)

    测试操作符

    • 在双括号结构里,问号(?)表示 C风格 的三元操作符
    • 在参数替换表达式里,问号(?)测试一个变量是否被设置了值
    # 输出:1
    a=10 && (( b = a<30?1:2 )) && echo $b
    
    # 测试一个变量是否被设置了值
    : ${PGDATA?"未设置值"}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通配符

    • 字符?被用于文件名扩展特性的文件名表达式的单字符匹配
    • 在扩展正则表达式中匹配任意一个字符
    cd / && ls -lh li?
    
    ls -l | grep -E 'bin?'
    
    • 1
    • 2
    • 3

    美元($)

    变量引用

    • 引用一个变量的内容
    VAR=1
    echo $VAR # 输出:1
    
    • 1
    • 2

    行的结尾

    • 在正则表达式里,一个$字符表示匹配一行的结尾
    # 把结尾的9换成1
    echo '123456789' | sed 's/9$/1/' # 输出123456781
    
    • 1
    • 2

    参数替换

    #! /bin/bash
    : ${1?"必须给定至少一个选项参数!"}
    
    sh tmp 
    # 报错:tmp: line 2: 1: 必须给定至少一个选项参数!
    
    • 1
    • 2
    • 3
    • 4
    • 5

    预定义变量

    $0:代表当前脚本的名称
    $!:后台运行的最后一个进程的PID
    $?:上一个命令退出的状态(0:成功,非0:失败)
    $*:当前shell参数集合(整体)
    $$:表示当前进程ID号码
    $#:代表当前shell的参数个数
    $@:当前shell参数集合(逐个读取)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    圆括号(())

    命令组

    • 一组由圆括号括起来的命令是新开一个子shell来执行的
    a=1
    (a=2; echo $a) # 输出:2
    echo $a # 输出:1
    
    • 1
    • 2
    • 3

    数组初始化

    array=(1 2 3)
    
    • 1

    整数扩展

    • 扩展并计算(( ))里的 整数 表达式
    echo $((1+2)) # 输出:3
    
    • 1

    花括号({})

    {xxx,yyy,zzz,…}

    # 连接file1,file2,和file3的内容并写到文件combined_file里去
    echo 1 > file1
    echo 2 > file2
    echo 3 > file3
    cat {file1,file2,file3} > combined_file
    : """
    输出:
    1
    2
    3
    """
    # 下面2种效果一致
    cp file4.txt file4.backup
    cp file4.{txt,backup}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 在扩展中的所有模式都不能包含空白字符,除非空白字符是被转义或引用的
    echo {file1,file2}\ :{\ A," B",' C'}
    # 输出:file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C
    
    • 1
    • 2

    代码块

    • 这个结构也是一组命令代码块,事实上,它是匿名的函数
    • 与一个函数所不同的,在代码块里的变量仍然能被脚本后面的代码访问
    { local a;a=1; }
    # 输出:-bash: local: can only be used in a function
    a=1
    { a=2; }
    echo $a # 输出:2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 由花括号括起的代码块可以引起输入输出的I/O重定向
    #! /bin/bash
    # 从/etc/fstab文件里按一次一行地读
    FILE=/etc/fstab
    {
        read line1
        read line2
    } < $FILE
    echo "First line in $File is:"
    echo "$line1"
    echo
    echo "Second line in $File is:"
    echo "$line2"
    exit 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 不像一个用圆括号括起来的命令组,一个用花括号括起的代码块不会以一个子shell运行
    #! /bin/bash
    FILE=~/test
    {
    echo 1
    echo 2
    echo 3
    } > $FILE
    
    sh tmp
    cat ~/test
    : """
    输出:
    1
    2
    3
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    {} \;

    • 路径名,基本上用于find命令里,它不是shell内建的
    • 如果 COMMAND 中包含 {},那么 find 命令将会用所有匹配文件的路径名来替换 “{}”
    find ~/ -name 'core*' -exec rm {} \;
    # 从用户的 home 目录中删除所有的 core dump文件.
    
    • 1
    • 2

    方括号([ ])

    测试

    [ 1 -eq 2 ]; echo $? # 输出:1
    [ 1 -eq 1 ]; echo $? # 输出:0
    [[ 1 -eq 2 ]]; echo $? # 输出:1
    [[ 1 -eq 1 ]]; echo $? # 输出:0
    
    • 1
    • 2
    • 3
    • 4

    数组元素

    • 在数组的上下文中,方括号表示数组的每个元素的数字编号
    ARRAY=(1 2 3)
    echo ${ARRAY[0]} # 输出:1
    echo ${ARRAY[1]} # 输出:2
    echo ${ARRAY[2]} # 输出:3
    
    • 1
    • 2
    • 3
    • 4

    字符集的范围

    • 用于正则表达式的一部分,方括号描述一个匹配的字符集范围
    echo '12A125ZF' | sed 's/[A-Z]/0/g' # 输出:12012500
    
    • 1

    大于小于和(><&)

    重定向

    ll -lh > ~/tmp.txt # 重定向ll -lh的输出到文件~/tmp.txt中去. 如果文件~/tmp.txt存在则将会被覆盖
    # 会重定向命令ll -lh标准输出(stdout)和标准错误(stderr)到文件~/tmp.txt中
    (ll -lh && 错误命令) &> ~/tmp.txt 
    (ll -lh && 错误命令) > tmp 2>&1
    # 把命令ll -lh的标准输出(stdout)重定向到标准错误
    (ll -lh && 错误命令) >&2 (stderr)
    ll -lh >> ~/tmp.txt # 把命令ll -lh的输出追加到文件~/tmp.txt,如果~/tmp.txt不存在,则它会被创建
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    cat <<EOF
    # 这里的注释会被打印
    Hello,sqlboy!
    EOF
    
    cat <<< Hello,sqlboy! # 这里的注释不会被打印
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • >| 强迫重定向 (即使noclobber选项设置), 这会强迫覆盖一个存在的文件
    echo 111 >| tmp
    
    • 1

    进程替换

    • 进程替换把一个进程的输出回馈给另一个进程
    diff <(ls -lh) <(ls)
    # 比较ls -lh的输出和ls的输出有什么不同
    
    • 1
    • 2

    整数比较

    • 真返回1,假返回0
    expr 1 \> 2     # 输出:0
    expr 3 \> 2     # 输出:1
    echo $((1 > 2)) # 输出:0
    echo $((3 > 2)) # 输出:1
    
    • 1
    • 2
    • 3
    • 4

    ASCII码比较

    [ "a" \< "A" ];echo $?  # 输出:1
    [ 97 \< 65 ];echo $?    # 输出:1
    [[ "a" < "A" ]];echo $? # 这里可能是个系统bug,输出:0
    [[ 97 < 65 ]];echo $?   # 输出:1
    [[ "c" < "t" ]];echo $? # 输出:0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    单词界线

    # 只匹配lib单词,不匹配lib64
    cd / && ll -lh | grep '\'
    
    • 1
    • 2

    后台运行

    • 一个后面跟一个&的命令会在后台运行
    sleep 10 &
    
    • 1

    逻辑与

    • 在测试结构中,&&操作只在测试条件两者 都为真时会返回0(成功)
    [[ 1 = 2 && 3 = 3 ]];echo $?    # 输出:1
    [ 1 = 2 ] && [ 3 = 3 ];echo $?  # 输出:1
    
    • 1
    • 2

    双竖线(||)

    逻辑或

    • 在一个测试结构中,||操作符当测试条件的任何一个为真时返回0 (成功)的标志
    [[ 1 = 2 || 3 = 3 ]];echo $?    # 输出:0
    [ 1 = 2 ] || [ 3 = 3 ];echo $?  # 输出:0
    
    • 1
    • 2

    短线(-)

    选项

    • 用于一个命令或过滤器的选项标志
    ls -lh
    
    • 1

    前缀

    • 用于一个操作符的前缀
    [[ 5 -eq $[15 / 3] ]];echo $? # 输出:0
    
    • 1

    重定向

    • 用于stdin或stdout重定向的源或目的
    tar cf - .
    
    file -  
    
    • 1
    • 2
    • 3

    先前的工作目录

    • 命令cd - 可以回到原来的工作目录,它使用了$OLDPWD 环境变量
    cd -; echo $OLDPWD  # 输出:/root
    cd -; echo $OLDPWD  # 输出:/
    
    • 1
    • 2

    负号或减号

    echo $[2-1]    # 输出:1
    echo $((2-1))  # 输出:1
    expr 2 - 1     # 输出:1
    
    • 1
    • 2
    • 3

    等号(=)

    赋值操作符

    a=1; echo $a # 输出:1
    
    • 1

    比较操作符

    if [ "1" = "1" ];then echo "True";fi # 输出:True
    
    • 1

    加号(+)

    加法运算

    echo $[1+2]    # 输出:3
    echo $((1+2))  # 输出:3
    expr 1 + 2     # 输出:3
    
    • 1
    • 2
    • 3

    选项

    • 一些命令和内建命令,用+来启用一些选项,用-来禁用它们
    chmod +x tmp.sh
    
    • 1

    百分号(%)

    取模

    • 取模 (一次除法的余数) 算术操作
    expr 16 % 3    # 输出:1
    echo $[16%3]   # 输出:1
    echo $((16%3)) # 输出:1
    
    • 1
    • 2
    • 3

    模式匹配

    VAR=12345678912345
    PATTERN=1*4
    # 从左到右最短匹配
    echo ${VAR#$PATTERN} # 输出:5678912345
    # 从左到右最长匹配
    echo ${VAR##$PATTERN} # 输出:5
    
    PATTERN=2*5
    # 从右到左最短匹配
    echo ${VAR%$PATTERN} # 输出:1234567891
    # 从右到左最长匹配
    echo ${VAR%%$PATTERN} # 输出:1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    波浪号(~)

    家目录

    • 与内部变量 $HOME 是一致的
    echo $HOME  # 输出:/root
    echo ~      # 输出:/root
    
    • 1
    • 2

    当前工作目录

    • 与外部变量$PWD是一致的
    cd /; echo ~+; echo $PWD  
    : """
    输出:
    /
    /
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    先前工作目录

    • 与外部变量$OLDPWD是一致的
    cd /; cd /root; echo ~-; echo $OLDPWD  
    : """
    输出:
    /
    /
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    正则表达式匹配

    [[ "123456" =~ [0-9]+ ]]; echo $?  # 输出:0
    
    • 1

    尖号(^)

    行首

    • 在正则表达式中, 字符"^"表达匹配一个文本行的开头
    # 匹配以lr开头的
    ll -lh | grep '^lr'
    
    • 1
    • 2
  • 相关阅读:
    VMware workstation的安装
    米家竞品分析
    联通面试题
    opengl glfw demo 下载,在windows vs2015中运行
    送女朋友的七夕礼物推荐,七夕送礼推荐
    .NET的各种对象在内存中如何布局[博文汇总]
    【C++ Boost库】原始计时器
    C++ STL教程
    c++学习笔记
    对HFish蜜罐捕捉到的样本分析
  • 原文地址:https://blog.csdn.net/qq_33445829/article/details/126703752