04@ 元字符

1|0元字符

元字符指的是能够被shell解释的特殊字符,每个特殊字符都有其特殊含义,这些字符一方面可用于变量值的运算、我们可以称之为运算符,另外一方面可以和shell命令配合使用来达到更高级的效果

1|1一、算数运算符

运算符 : + - * / %

1|01、算数运算符需要配合下述操作使用

1)整数运算: expr $(()) $[] let 2)#浮点运算: bc

1|02、算数运算详解

1)#bc是比较常用的linux计算工具了,而且支持浮点运算 [root@localhost ~]# res=`echo 1+1 | bc` [root@localhost ~]# echo $res 2 [root@localhost ~]# res=`echo 10 % 3 | bc` [root@localhost ~]# echo $res 1 [root@localhost ~]# res=`echo 1.2+1.3|bc` [root@localhost ~]# echo $res 2.5 [root@localhost ~]# res=`echo 5.0+3.0|bc` [root@localhost ~]# echo $res 8.0 [root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc` [root@localhost ~]# echo $res 1.66 [root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc` [root@localhost ~]# echo $res .83 2)#expr不支持浮点数计算,而且要注意数字与运算符中的空格 [root@localhost ~]# res=`expr 5 / 3` # 不支持浮点计算 [root@localhost ~]# echo $res 1 [root@localhost ~]# res=`expr 1+1` # 注意:要有空格 [root@localhost ~]# echo $res 1+1 [root@localhost ~]# res=`expr 1 + 1` [root@localhost ~]# echo $res 2 如果是乘法,如需要转义\* [root@egon ~]# expr 3 \* 10 30 [root@egon ~]# 3)#$(()) 同expr,不支持浮点数运算 #例如: [root@localhost ~]# echo $((1+1)) 2 [root@localhost ~]# echo $((1.0+2.0)) #不支持浮点运算符 -bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0" #注意: echo $(($num1+$num2)) # 也可以简写为 echo $((num1+num2)) echo $(((5-3)*2)) # 可以嵌套括号 4)#$[]同expr以及\$(()),不支持浮点运算​ [root@egon ~]# echo $[$num1+$num2] # 等同于 echo $[num1+num2] 333 [root@egon ~]# echo $[1.3+3.1] -bash: 1.3+3.1: 语法错误: 无效的算术运算符 (错误符号是 ".3+3.1" 5)#let 不支持浮点数运算,而且不支持直接输出,只能赋值 [root@localhost ~]# let res=1+1 [root@localhost ~]# echo $res 2 [root@localhost ~]# [root@localhost ~]# let res=50/5 [root@localhost ~]# echo $res 10 [root@localhost ~]# let c=1.3*3 -bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3" 6)#强调:整数与非整数之间运算会报错 [root@egon ~]# expr 1 + a expr: 非整数参数 [root@egon ~]# expr 1 + 1.3 expr: 非整数参数

1|2二、使用测试练习

1#脚本案例: 编写小脚本, 可以实现2位数加减乘除运算 [root@egon shell]# cat a.sh #!/bin/bash a=$1 b=$2 [ $# -ne 2 ] && { echo "请输入两位数字信息" exit } echo "a-b=$((a-b))" echo "a+b=$((a+b))" echo "a*b=$((a*b))" echo "a/b=$((a/b))" 2#脚本案例: 编写判断输入参数是否是整数信息脚本 #!/bin/bash a=$1 expr $a + 0 &>/dev/null # 只有整型加0才不会报错,浮点数及字符与0详解都会报错 [ $? -eq 0 ] && echo "输入的是整数信息" || echo "输入的是非整数信息" 3#如何利用脚本计算1+2+3+4..10总和数值 方法一: seq -s "+" 10|bc 方法二: echo {1..10}|tr " " "+"|bc 方法三: awk 'BEGIN{for (i=1; i<=10; i++) a=a+i; print a}'

1|3三、测试运算符

测试命令:test,详细可用man test查询 测试符号:[],注意只有一层中括号,中括号内左右两侧必须要有空格 test与 [] 效果都一样,参数也都一样

1|01、测试文件状态

  • -d 目录

    [root@egon ~]# test -d /etc/ ; echo $? 0 [root@egon ~]# [ -d /etc ];echo $? # 注意[]内左右两侧要有空格 0 #ps:下面关于[]用法都与test一样,不再举例
  • -s 文件长度 > 0、非空

    [root@egon ~]# touch a.txt [root@egon ~]# test -s a.txt ;echo $? # 文件为空则返回假 1 [root@egon ~]# test -s /etc/passwd ;echo $? # 文件不为空则返回假 0
  • -f 标准文件

    [root@egon ~]# test -f /etc/passwd;echo $? 0
  • -w 可写

    [egon@egon ~]$ touch a.txt [egon@egon ~]$ chmod a-w a.txt [egon@egon ~]$ [ -w a.txt ];echo $? # 返回假,注意,如果是root用户,无论如何都有写权限 1
  • -r 可读

    [egon@egon ~]$ ll a.txt -r--r--r--. 1 egon egon 292 817 21:48 a.txt [egon@egon ~]$ test -r a.txt;echo $? 0
  • -x 可执行

    [egon@egon ~]$ ll a.txt -r--r--r--. 1 egon egon 292 817 21:48 a.txt [egon@egon ~]$ test -x a.txt;echo $? 1
  • -L 符号连接

    [root@egon ~]# ll -d /lib64 lrwxrwxrwx. 1 root root 9 714 03:33 /lib64 -> usr/lib64 [root@egon ~]# test -L /lib64;echo $? 0
  • -u 文件有 suid 位设置

    [root@egon ~]# ll /usr/bin/passwd -rwsr-xr-x. 1 root root 27832 610 2014 /usr/bin/passwd [root@egon ~]# [ -u `which passwd` ];echo $? 0 [root@egon ~]# [ -u `which ls` ];echo $? 1
  • -c 文件是否为磁盘文件

[root@web01 mnt]# test -c /dev/tty;echo $? 0 [root@web01 mnt]# test -c /root/.bashrc;echo $? 1 [root@web01 mnt]#

1|02、 字符串测试

  • == 两个字符串相等

    [root@egon ~]# [ "aaa" == "aaa" ];echo $? 0
  • != 两个字符串不相等

    [root@egon ~]# [ "aaa" != "aaa" ];echo $? 1
  • -z 字符串长度为零

    [root@egon ~]# ip="" [root@egon ~]# [ -z "$ip" ];echo $? # 注意引号 0 [root@egon ~]# ip='1.1.1.1' [root@egon ~]# [ -z "$ip" ];echo $? 1
  • -n 字符串长度不为零

    [root@egon ~]# [ -n "$ip" ];echo $? # 注意加引号 1

1|03、测试数值

test与[]也可以测试数值,与 [[]]和(())效果一样,下一小节会详细介绍[[]]和(())

-eq #等于 -ne #不等于 -gt #大于 -lt #小于 -ge #大于等于 -le #小于等于 -a #并且 -o #或者
[root@egon ~]# [ 10 -eq 10 ];echo $? 0 [root@egon ~]# [ 10 -eq 10 -a 10 > 3 ];echo $? 0 #示例: [root@egon ~]# disk_use=$(df -P |grep '/$' |awk '{print $5}' |awk -F% '{print $1}') [root@egon ~]# [ $disk_use -gt 10 ] && echo "warn......" warn...... [root@egon ~]# [ $(id -u) -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户" 当前是超级用户

1|4四、关系运算符

关系运算符需要配合(())使用(注意(())属于C语言风格的比较),最终都是用来当if判断或者while循环的条件" [[]]和(())"

< \> <= \>= == != && ||
#示列: [root@egon ~]# x=100 [root@egon ~]# (($x>10)) [root@egon ~]# echo $? 0 [root@egon ~]# (($x < 10));echo $? 1 [root@egon ~]# (($x == 100));echo $? 0 [root@egon ~]# (($x != 100));echo $? 1 [root@egon ~]# (($x != 100)) && (("egon" == "egon")) [root@egon ~]# echo $? 1 [root@egon ~]# (($x != 100)) || (("egon" == "egon")) [root@egon ~]# echo $? 0 [root@egon ~]# (($x != 100 && "egon" == "egon"));echo $? 1 [root@egon ~]# (($x != 100 || "egon" == "egon"));echo $? 0

1|5五、赋值运算符

= [root@egon ~]# x=10 [root@egon ~]# echo $x 10 += [root@web01 /]# x=10 [root@web01 /]# ((x+=10)) [root@web01 /]# echo $x 20 [root@web01 /]# *= [root@web01 /]# x=10 [root@web01 /]# ((x*=10)) [root@web01 /]# echo $x 100 [root@web01 /]# [root@web01 /]# x=10 [root@web01 /]# ((x*=5)) [root@web01 /]# echo $x 50 [root@web01 /]# /= [root@web01 /]# x=10 [root@web01 /]# ((x/=5)) [root@web01 /]# echo $x 2 %= [root@web01 /]# x=10 [root@web01 /]# ((x%=100)) [root@web01 /]# echo $x 10 [root@web01 /]# [root@web01 /]# x=13 [root@web01 /]# ((x%=100)) [root@web01 /]# echo $x 13 [root@web01 /]#

1|6六、扩展

1|01、补充[[]]

[[]]与[]基本一样,不同的是[[]]支持正则匹配,不过要注意的是必须在内层中括号内左右两侧加空格 [root@egon ~]# [[ "$USER" == "root" ]];echo $? # 注意内层[]中包含的内容必须左右两侧加空格 0 [root@egon ~]# [[ "$USER" == "root" ]];echo $? # 一个等号也行两个等号也可以额 0 #此外[[]]内部是可以使用正则的,注意:正则表达式不要加引号 [root@egon ~]# [[ "$USER" =~ "^root$" ]];echo $? # 正则表达式不要加引号 1 [root@egon ~]# [[ "$USER" =~ ^root$ ]];echo $? # 正则表达式不要加引号 0 [root@egon ~]# [[ ! "$USER" =~ t$ ]] && echo 此时不是管理员登录 || echo 是管理员登录 是管理员登录 [root@egon ~]# num1=123 [root@egon ~]# [[ "$num1" =~ ^[0-9]+$ ]];echo $? # 判断是否是数字 0 [root@egon ~]# [[ "$num1" =~ ^[0-9]+$ ]] && echo "是数字" 是数字 [root@egon ~]# num2=abc123de [root@egon ~]# [[ "$num2" =~ ^[0-9]+$ ]];echo $? 1 [root@egon ~]# [[ "$num2" =~ ^[0-9]+$ ]] || echo "num2不是数字" num2不是数字

企业面试题1: 传入两个数值信息, 自动让脚本显示数值比较情况

[root@egon shell]# cat num.sh #!/bin/bash [ $# -ne 2 ] && echo "只能传入两个整数" && exit [[ ! $1 =~ ^[0-9]+$ ]] && echo "参数1必须是整数" && exit [[ ! $2 =~ ^[0-9]+$ ]] && echo "参数2必须是整数" && exit [[ $1 -lt $2 ]] && echo "$1 < $2" [[ $1 -gt $2 ]] && echo "$1 > $2" [[ $1 -eq $2 ]] && echo "$1 = $2" [root@egon shell]# chmod +x num.sh [root@egon shell]# ./num.sh 17 37 17 < 37

1|02、补充浮点数的比较

# 需要注意的是:bc的结果为1代表真,为0代表假 [root@egon ~]# echo "10.3 >= 10.1" | bc 1 [root@egon ~]# echo "10.3 != 10.1" | bc 1 [root@egon ~]# echo "10.3 != 10.3" | bc 0 # 应用 [root@egon ~]# x=10.3 [root@egon ~]# y=10.1 [root@egon ~]# [ `echo "$x >= $y" | bc` -eq 1 ] && echo "$x 大于 $y" 10.3 大于 10.1

1|7七、总述

1)条件测试:

格式1: test 条件表达式 格式2: [ 条件表达式 ] 格式3: (()) 数值比较,运算 C语言 格式4: [[ 条件表达式 ]],支持正则 =~

2)结合$符号

$[] # 整数运算 $(()) # 整数运算 $() # 命令替换

3)其他

() # 子shell中执行

1|8八、 其他元字符

1|01、`` 与$():取命令的结果

[root@localhost ~]# echo `pwd` /root [root@localhost ~]# echo $(pwd) /root 不一样的地方在于$()可以嵌套,而``不能嵌套 [root@localhost ~]# echo $(ls $(pwd)) # 练习 [root@aliyun test]# touch $(date +%F)_bak.tar.gz [root@aliyun test]# ls 2020-08-24_bak.tar.gz

1|02、~家目录

1|03、.与…

1|04、!调用历史命令、取反

1)#调用历史命令 [root@egon ~]# !1066 [root@egon ~]# !ls # 匹配最近的一次历史命令 2)#取反1:对命令的结果取反 [root@egon ~]# ! pwd /root [root@egon ~]# echo $? 1 3)#取反2:效果与^雷同 [root@localhost ~]# touch /test/{1.txt,2.txt,a.txt,aaa_bbb.txt} [root@localhost ~]# find /test ! -name 1.txt /test /test/2.txt /test/a.txt /test/aaa_bbb.txt [root@localhost ~]# ls /test/[!0-9].txt # .txt前只有一个字符,但是非数字 /test/a.txt [root@localhost ~]# ls /test/[^0-9].txt # .txt前只有一个字符,但是非数字 /test/a.txt [root@aliyun test]# ls -a /etc/skel/.[!.]*

1|05、@无特殊意义

1|06、#注释

1|07、$取变量值

[root@localhost ~]# x=1 [root@localhost ~]# echo $x 1

1|08、%、-、+运算符,注意%可以与jobs配合“kill %工作号”杀后台进程。-减号还有区间及cd -回到上一级的意思

# 数学运算 # 1、bc是比较常用的linux计算工具了,而且支持浮点运算: [root@localhost ~]# res=`echo 1+1 | bc` [root@localhost ~]# echo $res 2 [root@localhost ~]# res=`echo 10 % 3 | bc` [root@localhost ~]# echo $res 1 [root@localhost ~]# res=`echo 1.2+1.3|bc` [root@localhost ~]# echo $res 2.5 [root@localhost ~]# res=`echo 5.0+3.0|bc` [root@localhost ~]# echo $res 8.0 [root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc` [root@localhost ~]# echo $res 1.66 [root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc` [root@localhost ~]# echo $res .83 # 2、expr不支持浮点数计算。而且要注意数字与运算符中的空格 [root@localhost ~]# res=`expr 5 / 3` # 不支持浮点计算 [root@localhost ~]# echo $res 1 [root@localhost ~]# res=`expr 1+1` # 注意:要有空格 [root@localhost ~]# echo $res 1+1 [root@localhost ~]# res=`expr 1 + 1` [root@localhost ~]# echo $res 2 [root@localhost ~]# res=`expr 5 \* 3` # 在expr中*号要转义才能用,否则报语法错误 [root@egon ~]# echo $res 15 # 3、$(()) 同expr,不支持浮点数运算 [root@localhost ~]# echo $((1+1)) 2 [root@localhost ~]# echo $((1.0+2.0)) -bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0" # 4、$[]同expr以及$(()),不支持浮点运算 [root@localhost ~]# x=1 [root@localhost ~]# echo $[$x+1] 2 # 5、let 不支持浮点数运算,而且不支持直接输出,只能赋值 [root@localhost ~]# let res=1+1 [root@localhost ~]# echo $res 2 [root@localhost ~]# [root@localhost ~]# let res=50/5 [root@localhost ~]# echo $res 10 [root@localhost ~]# let c=1.3*3 -bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3" [root@aliyun test]# x=1 [root@aliyun test]# let x+=10 [root@aliyun test]# echo $x 11

1|09、^同!一样

1|010、&后台运行

[root@localhost home]# echo "hello";sleep 3;echo "world" &

1|011、*任意多个字符

[root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt [root@localhost ~]# rm -rf *.txt [root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt a1c.txt [root@localhost ~]# ls *.txt 1.txt 2.txt a1c.txt aaa.txt aa.txt

1|012、()在子shell中执行

[root@localhost ~]# (x=1) [root@localhost ~]# echo $x 应用 [root@localhost ~]# (umask 066;touch a.txt) # umask的设置只在子shell中有效 [root@localhost ~]# ll a.txt -rw-------. 1 root root 0 813 15:22 a.txt [root@localhost ~]# touch b.txt [root@localhost ~]# ll b.txt -rw-r--r--. 1 root root 0 813 15:23 b.txt

1|013、_下划线:无特殊意义,可以用于名字的声明

[root@localhost ~]# tar -czvf `date +%F_%H:%M:%S`_bak.tar.gz /etc/

1|014、=赋值,==判断相等性

[root@localhost ~]# [ 1 == 1 ] # 条件1 == 1的左右两边必须有空格 [root@localhost ~]# echo $? # 判断上一条命令的结果是否为真,0=》true 0

1|015、|管道:把一个进程的处理结果传递给另外一个进程

[root@localhost ~]# ps aux | grep python |管道命令的作用,是将左侧命令的标准输出转换为标准输入,提供给右侧命令作为参数。但是,大多数命令都不接受标准输入作为参数,只能直接在命令行输入参数,这导致无法用管道命令传递参数。比如echo命令就不接受管道传参。 $ echo "hello world" | echo xargs命令的作用,是将标准输入转为命令行参数,例如 $ echo "hello world" | xargs echo hello world [root@localhost ~]# find /home/ -type d -name "test*" |xargs ls 1.txt 2.txt 3.txt [root@localhost ~]# ls /home/test 1.txt 2.txt 3.txt

1|016、\转义特殊字符

[root@localhost ~]# mkdir a\ b.txt # 虽然可以,但不推荐 [root@localhost ~]# ll 总用量 0 drwxr-xr-x. 2 root root 6 813 15:35 a b.txt [root@localhost ~]# echo $RMB # 默认会当成变量 [root@localhost ~]# echo '$RMB' # 取消特殊意义 $RMB [root@localhost ~]# echo \$RMB # 取消特殊意义 $RMB

1|017、[]条件测试,后续会详细介绍

[root@localhost ~]# name="egon" [root@localhost ~]# [ $name == "egon" ];echo $? 0 [root@localhost ~]# name="adf" [root@localhost ~]# [ $name == "egon" ];echo $? 1 [root@localhost ~]# [ -d /test ];echo $? 0 [root@localhost ~]#

1|018、引号

'' 强引用(在单引号中都视为普通字符) " " 弱引用 (在双引号中保留变量) [root@localhost ~]# x=111 [root@localhost ~]# echo "$x" 111 [root@localhost ~]# echo '$x' $x [roo

1|019、;与&&与||连接多条命令

[root@localhost home]# gagaga;ls # 不论前一条命令运行成功与否,都会执行后续命令 bash: gagaga: 未找到命令... egon [root@localhost home]# gagaga && ls # 只有前一条命令执行成功,才会执行后续命令 bash: gagaga: 未找到命令... [root@localhost home]# ls /test || mkdir /test # 前一条命令执行不成功才会执行后续命令 0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt

1|020、:空命令,真值

[root@egon ~]# : [root@egon ~]# echo $? 0

1|021、/路径分隔符

1|022、{}循环列表

[root@localhost home]# touch /test/{0..9}.txt [root@localhost home]# ls /test/ 0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt [root@localhost ~]# touch {1..3}{a..d}.txt [root@localhost ~]# ls 1a.txt 1b.txt 1c.txt 1d.txt 2a.txt 2b.txt 2c.txt 2d.txt 3a.txt 3b.txt 3c.txt 3d.txt [root@egon ~]# x=100 [root@egon ~]# echo ${x}% # 控制变量名的范围 100% [root@egon ~]# [root@egon ~]# echo $xrmb [root@egon ~]# echo ${x}rmb 100rmb

1|023、重定向

> >> 输出重定向 < << 输入重定向 > 覆盖 >> 追加 [root@localhost home]# cat >> a.txt << EOF > 111 > 222 > 333 > EOF 0标准输入、1标准正确输出、2标准错误输出,&标准正确和错误输出 [root@localhost home]# pwd 1>a.txt [root@localhost home]# cat a.txt /home [root@localhost home]# gagag 2>a.txt [root@localhost home]# cat a.txt bash: gagag: 未找到命令... [root@localhost home]# gagaga &>/dev/null < << 输入重定向 [root@localhost ~]# mysql -uroot -p123 < bbs.sql [root@localhost home]# grep root < /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@localhost home]# dd if=/dev/zero of=/a.txt bs=1M count=10 记录了10+0 的读入 记录了10+0 的写出 10485760字节(10 MB)已复制,0.024387 秒,430 MB/秒 [root@localhost home]# dd </dev/zero >/b.txt bs=1M count=10 记录了10+0 的读入 记录了10+0 的写出 10485760字节(10 MB)已复制,0.0202365 秒,518 MB/秒 [root@localhost home]# ll /a.txt -rw-r--r--. 1 root root 10485760 813 16:02 /a.txt [root@localhost home]# ll /b.txt -rw-r--r--. 1 root root 10485760 813 16:03 /b.txt

1|024、?任意一个字符

[root@localhost ~]# ls ??.txt aa.txt [root@localhost ~]# ls a?c.txt a1c.txt [root@localhost ~]# rm -rf *.txt

1|025、范围中的任意一个字符 [12] [ac] [a-z] [0-9]

[root@localhost ~]# touch a1c a2c axc aXc axd [root@localhost ~]# ls a?c a1c a2c axc aXc [root@localhost ~]# ls a[1x]c a1c axc [root@localhost ~]# ls a[a-z]c axc aXc [root@localhost ~]# ls a[A-Z]c # 不区分大小写 axc aXc [root@localhost ~]# ls a[x]c axc [root@localhost ~]# ls a[X]c aXc [root@localhost ~]# ls a[0-9]c a1c a2c [root@localhost ~]# ls /dev/sd[a-z]* /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb1

__EOF__

本文作者ଲ小何才露煎煎饺
本文链接https://www.cnblogs.com/zeny/p/15121526.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ଲ小何才露煎煎饺  阅读(120)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示