Shell常用的特殊字符

 ; 分号

使用分号可以在一行使用多个命令

[root@localhost ~]# touch a.txt;ls
anaconda-ks.cfg  a.txt  initial-setup-ks.cfg

;; 双分号

专用于case,每个条件块以;;结束

[root@localhost shell]# cat ex_case.sh 
#!/bin/bash

case "$1" in
cat)
echo 'is a cat.'
echo 'end'
;;
dog)
echo is a dog.;;
*)
echo "bash $0 dog|cat"
;;
esac
[root@localhost shell]# bash ex_case.sh dog
is a dog.

 . 点号(dot)

点号在不同场景有着不同的含义,在目录路径中,一个点代表当前工作目录,两个点代表父目录;当一个文件以点号开头,表示一个隐藏文件;在正则表达式,点号代表匹配单个字符;

点号可以用于执行某个文件,同样,在脚本中,用于导入文件,等于source指令。

[root@localhost shell]# cat a.txt
name=david

[root@localhost shell]# cat a.sh
#!/bin/bash

# 这里的‘点号’等于 source,表示引入a.txt,类似python的import导入一个模块文件
. a.txt
echo $name

[root@localhost shell]# . a.sh
david

 '' 单引号和 "" 双引号

引号代表字符串,单引号不能解释$符号,不能变量转换。

[root@localhost shell]# name=tom
[root@localhost shell]# echo '$name'
$name
[root@localhost shell]# echo "$name"
tom

`` 反引号

相当于$()表示命令替换,将执行命令结果传给变量参数

[root@localhost shell]# td=`date +%F`
[root@localhost shell]# echo today $td
today 2020-10-16

: 冒号

表示零命令,返回True,也用于函数等,作为占位符

[root@localhost shell]# :
[root@localhost shell]# echo $?
0
[root@localhost shell]# cat /dev/null > a.txt 
[root@localhost shell]# : > a.txt           # 写法更简短,等于上面

 ! 感叹号

用于否定

? 问号

正则表达式中,表示匹配任一字符;也用于三元运算中

三元运算符语法是“条件表达式?表达式1:表达式2”,使用这个算法可以使调用数据时逐级筛选。

[root@localhost shell]# ls
a.sh  a.txt  ex_case.sh
[root@localhost shell]# ls ?.sh
a.sh
[root@localhost shell]# cat a.sh
#!/bin/bash
a=100
(( t = a<45?7:11 ))   # 三元运算
#       ^  ^ ^
# If a < 45, then t = 7, else t = 11."  # a=100
echo "t = $t "                          
[root@localhost shell]# bash a.sh
t = 11 

$  变量符号,正则表达式表示行尾

${} 变量的正则表达式

${parameter},等于$parameter,即是变量参数的值,可用于变量和字符串连接起来

[root@localhost shell]# cat a1.sh 
#!/bin/bash

your_id=${USER}-on-${HOSTNAME}
echo "$your_id"
echo "Old \$PATH = $PATH"
export PATH=${PATH}:/opt/bin    # Add /opt/bin to $PATH
echo "New \$PATH = $PATH"
[root@localhost shell]# bash a1.sh
root-on-localhost.localdomain
Old $PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
New $PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/opt/bin

${parameter-default}, ${parameter:-default}  

如果参数未定义,则使用default,这两个几乎是一样的,平时使用${parameter-default}更简短

[root@localhost shell]# cat a2.sh 
#!/bin/bash

var1=1
var2=2
echo ${var1-$var2} # 1
echo ${var3-$var2} # 2
echo ${username-`whoami`} # exe whoami

username0=
echo "username0 = ${username0-`whoami`}" # exe username0

[root@localhost shell]# bash a2.sh 
1
2
root
username0 = 

${parameter=default}, ${parameter:=default}
如果parameter未定义,则设置值为default

[root@localhost shell]# echo ${var=abc}
abc
[root@localhost shell]# echo ${var=xyz}  # 因为var的值已经定义
abc

 $*, $@ 所有定位参数

 $*和 $@要加引号,符号 $* 将所有的引用变量视为一个整体。但符号 $@ 则仍旧保留每个引用变量的区段观念。

 当$*没有加双引号,效果和$@效果是一样的。

[root@localhost shell]# cat argslist2.sh 
#!/bin/bash
if [ ! -n "$1" ]
then
    echo "usage:`basename $0` arg1 arg2..."
    exit 1
fi

index=1
echo "Listing args with \"\$*\":"
# $* 将所有位置参数当做整体一个单词
for arg in "$*"
do
    echo "args #$index=$arg"
    let "index+=1"
done

index=1
echo "Listing args with \"\$*\"(unquoted):"
 # $* 将所有位置参数当做独立的单词
for arg in $*
do
    echo "args #$index=$arg"
    let "index+=1"
done


index=1
echo "Listing args with \"\$@\":"
 # $@ 将所有位置参数当做独立的单词
for arg in "$@"
do
    echo "args #$index=$arg"
    let "index+=1"
done

index=1
echo "Listing args with \"\$@\"(unquoted):"
 # $@ 将所有位置参数当做独立的单词
for arg in $@
do
    echo "args #$index=$arg"
    let "index+=1"
done
[root@localhost shell]# bash argslist2.sh one two three
Listing args with "$*":
args #1=one two three
Listing args with "$*"(unquoted):
args #1=one
args #2=two
args #3=three
Listing args with "$@":
args #1=one
args #2=two
args #3=three
Listing args with "$@"(unquoted):
args #1=one
args #2=two
args #3=three

$# 位置参数的总数量

$$ 当前环境的进程ID
() 括号
1)命令组
括号内的命令列表启动一个子shell
2)数组初始化
 用来表示数组
 [root@localhost shell]# ( list=(1 3 5 7); for i in ${list[*]}; do echo $i; done )
1
3
5
7

 {xxx,yyy,zzz,...} 内容扩展

[root@localhost shell]# cp /data/shell/{file2,file3,a.txt} /tmp

{a..z} 具有顺序性质的内容扩展

[root@localhost shell]# echo {1..9}
1 2 3 4 5 6 7 8 9
[root@localhost shell]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

[ ] 和 [[ ]] 中括号和双中括号

双中括号用法一样,但是双中括号比中括号更加灵活,可以用于and(&&) or(||)等逻辑判断,用于[]中就会报错
#!/bin/bash
file=/etc/passwd
# use [] is also valid
if [[ -e $file ]]
then 
 echo "passwd file exists."
fi
# if use [] will report an error.
if [[ -e $file && -e /etc/hosts ]]
then
 echo "both file exists."
else
 echo "no exists."
fi

 $[ ... ] 计算整数之和,同$((...))

[root@localhost ~]# echo $[5+3]
8
[root@localhost ~]# echo $[5+3]
8
[root@localhost ~]# echo $((5+3))
8

 \<...\> 定位符号

\<the\> 在二则表达式中,用于匹配单词边界,比如只匹配‘the’,不匹配‘them’、‘there’等

[root@localhost shell]# cat textfile 
This is line 1, of which there is only one instance.
This is the only instance of line 2.
This is line 3, another line.
This is line 4.
[root@localhost shell]# grep '\<the\>' textfile 
This is the only instance of line 2.

 & 后台运行

- 破折号

重定向stdin或stdout

[root@localhost shell]# cat -

david

david

tom

tom

…

Ctrl-D

正如例子所示,键盘stdin什么内容就会stdout什么内容

破折号使用场景一:

通过tar打包和解包方式,复制目录下的内容到别的地方,等于cp -a /tmp/* /mnt

(cd /tmp && tar cf - . ) | (cd /mnt && tar xpvf -)

破折号使用场景二:

#!/bin/bash
# Set date in backup filename.
BACKUPFILE=backup-$(date +%F)
# If no BACKUPFILE variable,it will default to 'backup.tar.gz'.
archive=${BACKUPFILE-backup}
# Backup of all files changed in last day.
tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
# ----------------------------------------------------------------
# Another way:
# find . -mtime -1 -type f -print | xargs tar cvf $archive.tar
# find /etc -mtime -1 -type f -exec tar cvf $archive.tar {} \;
echo "Directory $PWD backed up in archive file \"$archive.tar\"."
exit 0
[root@localhost shell]# bash backupfile.sh 
./textfile
./backgroup.sh
./filetext
./test.tar.bz2
./tmp.tar.gz2
./test.sh
./backupfile.sh
Directory /data/shell backed up in archive file "backup-2020-10-18.tar".

 IFS(internal filed separator) 内部字符分隔符

IFS环境变量定义了bash shell 用作字段分隔符的一系列字符。默认会将下列字符当做字符分隔符:

# 默认会将下列字符当做字符分隔符:空格、制表符、换行符
[root@localhost shell]# set | grep IFS
IFS=$' \t\n'
# env为空,说明IFS是局部变量
[root@localhost shell]# env |grep IFS

如果需要使用其它分隔符,那需要临时修改IFS环境变量:

#!/bin/bash
# find files in the PATH

IFS=:
for folder in $PATH
do
    echo $folder
    for file in $folder/*
    do
        if [ -x $file ]
        then
            echo "    $file"
        fi
    done
done

 

[root@localhost shell]# bash how_many_executable.sh 
1317 commands, and 2 entries that wheren't executanle. 
posted @ 2020-10-19 14:25  z寒江雪  阅读(1052)  评论(0编辑  收藏  举报