【shell 特殊字符】

井号(#)

注释

  • 以一个#开头的行 (#!是例外) 是注释行
  • 注释也可以出现在一个命令语句的后面
  • 注释行前面也可以有空白字符
  • 在echo命令给出的一个转义的#字符并不会开始一个注释
# 输出:这里
echo 这里 #是一个注释

# 输出:这里#不是一个注释
echo 这里#不是一个注释

# 输出:这里 #不是一个注释
echo 这里 \#不是一个注释

# 输出:这里 #不是一个注释
echo "这里 #不是一个注释"

# 输出:这里 #不是一个注释
echo '这里 #不是一个注释'

# 我是注释

分号(;)

命令分割符

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

双分号(;;)

case语句分支的结束符

case "${VAR}" in 
    abc)
        echo "\${VAR} = 123"
        ;;
    xyz) 
        echo "\${VAR} = 456"
        ;;
esac

点(.)

等同于source

. ~/.bash_profile
# 等效于
source ~/.bash_profile

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

  • 当点(.)以一个文件名为前缀时,起作用使该文件变成了隐藏文件
  • 作为目录名时,单个点(.)表示当前目录,两个点(…)表示上一级目录
# 不显示隐藏文件
ls -l ~
# 显示隐藏文件
ls -la ~

cd .
pwd # 输出:/root
cd ..
pwd # 输出:/

字符匹配

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

双引号(")

字符串引用(部分引用)

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

单引号(')

字符串引用(完全引用)

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

逗号(,)

逗号操作符

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

后斜杠(\)

转义符

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

# "和'转义
echo \'  # 输出:'
echo \"  # 输出:"
echo "\"" # 输出:"

前斜杠(/)

文件路径的分隔符

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

除法

expr 15 / 3 # 输出:5

斜引号(`)

命令替换

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

冒号(:)

空命令

  • 空操作(即什么操作也不做)
  • 它一般被认为是和shell的内建命令true是一样的
  • 它的退出状态码是真(即0)
:
echo $? # 输出:0

if [ : ]; then echo '123';fi

分隔符

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

变量扩展/子串替换

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

和重定向符同时使用

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

感叹号(!)

取反

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

间接引用

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

历史命令

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

星号(*)

通配符

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

模式匹配

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

算数操作符

  • 星号(*)表示乘法运算符
  • 两个星号(**)表示求幂运算符
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

问号(?)

测试操作符

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

# 测试一个变量是否被设置了值
: ${PGDATA?"未设置值"}

通配符

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

ls -l | grep -E 'bin?'

美元($)

变量引用

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

行的结尾

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

参数替换

#! /bin/bash
: ${1?"必须给定至少一个选项参数!"}

sh tmp 
# 报错:tmp: line 2: 1: 必须给定至少一个选项参数!

预定义变量

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

圆括号(())

命令组

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

数组初始化

array=(1 2 3)

整数扩展

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

花括号({})

{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}
  • 在扩展中的所有模式都不能包含空白字符,除非空白字符是被转义或引用的
echo {file1,file2}\ :{\ A," B",' C'}
# 输出:file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C

代码块

  • 这个结构也是一组命令代码块,事实上,它是匿名的函数
  • 与一个函数所不同的,在代码块里的变量仍然能被脚本后面的代码访问
{ local a;a=1; }
# 输出:-bash: local: can only be used in a function
a=1
{ a=2; }
echo $a # 输出:2
  • 由花括号括起的代码块可以引起输入输出的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
  • 不像一个用圆括号括起来的命令组,一个用花括号括起的代码块不会以一个子shell运行
#! /bin/bash
FILE=~/test
{
echo 1
echo 2
echo 3
} > $FILE

sh tmp
cat ~/test
: """
输出:
1
2
3
"""

{} \;

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

方括号([ ])

测试

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

数组元素

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

字符集的范围

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

大于小于和(><&)

重定向

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不存在,则它会被创建
cat <<EOF
# 这里的注释会被打印
Hello,sqlboy!
EOF

cat <<< Hello,sqlboy! # 这里的注释不会被打印
  • >| 强迫重定向 (即使noclobber选项设置), 这会强迫覆盖一个存在的文件
echo 111 >| tmp

进程替换

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

整数比较

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

ASCII码比较

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

单词界线

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

后台运行

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

逻辑与

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

双竖线(||)

逻辑或

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

短线(-)

选项

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

前缀

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

重定向

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

file -  

先前的工作目录

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

负号或减号

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

等号(=)

赋值操作符

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

比较操作符

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

加号(+)

加法运算

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

选项

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

百分号(%)

取模

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

模式匹配

VAR=12345678912345
PATTERN=1*4
# 从左到右最短匹配
echo ${VAR#$PATTERN} # 输出:5678912345
# 从左到右最长匹配
echo ${VAR##$PATTERN} # 输出:5

PATTERN=2*5
# 从右到左最短匹配
echo ${VAR%$PATTERN} # 输出:1234567891
# 从右到左最长匹配
echo ${VAR%%$PATTERN} # 输出:1

波浪号(~)

家目录

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

当前工作目录

  • 与外部变量$PWD是一致的
cd /; echo ~+; echo $PWD  
: """
输出:
/
/
"""

先前工作目录

  • 与外部变量$OLDPWD是一致的
cd /; cd /root; echo ~-; echo $OLDPWD  
: """
输出:
/
/
"""

正则表达式匹配

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

尖号(^)

行首

  • 在正则表达式中, 字符"^"表达匹配一个文本行的开头
# 匹配以lr开头的
ll -lh | grep '^lr'
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
shell中,有一些特殊字符具有特殊的含义和功能。以下是一些常见的shell特殊字符: 1. #:表示注释的开始,后面的内容将被忽略。 2. ;:用于分隔多个命令,可以在一行中执行多个命令。 3. ;;:用于在case语句中分隔不同的模式。 4. .:表示当前目录,也可以用于执行脚本文件。 5. ,:用于在数组中分隔不同的元素。 6. /:表示路径的分隔符。 7. \:用于转义特殊字符,使其失去特殊含义。 8. 'string':单引号内的内容将被视为纯文本,不进行变量替换和转义。 9. "string":双引号内的内容可以进行变量替换和转义,但某些特殊字符仍保持特殊含义。 10. $:用于引用变量的值。 11. ${}:用于引用变量的值,并可以进行进一步的操作。 12. $?:用于获取上一个命令的退出状态。 13. $$:表示当前shell进程的PID。 14. $*:表示所有位置参数的列表。 15. "string"*:表示以"string"开头的文件名列表。 16. **:用于匹配任意层级的目录和文件。 17. ?:用于匹配单个字符。 18. ::用于空命令或作为占位符。 19. ^:用于表示行的起始位置。 20. $#:表示位置参数的个数。 21. $@:表示所有位置参数的列表。 22. `command`:用于执行命令并将其输出作为字符串返回。 23. {}:用于创建代码块或进行字符串替换。 24. \[\]:用于条件测试或字符范围匹配。 25. \[\[\]\]:用于高级条件测试。 26. ():用于创建子shell或进行命令组合。 27. (()):用于进行算术运算。 28. ||:表示逻辑或。 29. &&:表示逻辑与。 30. {xx,yy,zz,...}:用于生成多个值的列表。 31. ~:表示当前用户的主目录。 32. ~+:表示当前工作目录。 33. ~-:表示上一个工作目录。 34. &:用于后台执行命令。 35. \<...\>:用于匹配整个单词。 36. +:用于表示正数或开启某些选项。 37. -:用于表示负数或关闭某些选项。 38. %=:用于进行模式替换。 39. ==:用于比较两个字符串是否相等。 40. !=:用于比较两个字符串是否不相等。 这些特殊字符shell脚本中具有重要的作用,可以用于控制命令的执行流程、变量的引用和替换、字符串的处理等。 #### 引用[.reference_title] - *1* *3* [linux特殊符号大全](https://blog.csdn.net/weixin_33712881/article/details/92939882)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [shell中特殊符号](https://blog.csdn.net/weixin_34216036/article/details/92412548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sqlboy-yuzhenc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值