shell中的特殊字符
* 星号
- 作为匹配文件名扩展的一个通配符,能自动匹配给定目录下的每一个文件;
bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh
- 正则表达式中可以作为字符限定符,表示其前面的匹配规则匹配任意次;
-算术运算中表示乘法。
** 双星号
- 算术运算中表示求幂运算。
? 问号
表示条件测试;
在双括号内表示C风格的三元操作符
(( var0 = var1<98?9:21 ))
# ^ ^
# if [ "$var1" -lt 98 ]
# then
# var0=9
# else
# var0=21
# fi
- 参数替换表达式中用来测试一个变量是否设置了值;
#!/bin/bash
# Check some of the system's environmental variables.
# This is good preventative maintenance.
# If, for example, $USER, the name of the person at the console, is not set,
#+ the machine will not recognize you.
: ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?}
echo
echo "Name of the machine is $HOSTNAME."
echo "You are $USER."
echo "Your home directory is $HOME."
echo "Your mail INBOX is located in $MAIL."
echo
echo "If you are reading this message,"
echo "critical environmental variables have been set."
echo
echo
作为通配符,用于匹配文件名扩展特性中,用于匹配单个字符;
正则表达式中,表示匹配其前面规则0次或者1次。
$ 美元符号
- 作为变量的前导符,用作变量替换,即引用一个变量的内容
var1=5
var2=23skidoo
echo $var1 # 5
echo $var2 # 23skidoo
- 在正则表达式中被定义为行末(End of line)。
“${}”
- 参数替换 ,基本作用和$一致,在链接字符串方面稍有差别
your_id=${USER}-on-${HOSTNAME}
echo "$your_id"
#
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin # Add /opt/bin to $PATH for duration of script.
echo "New \$PATH = $PATH"
$’…’
- 引用展开
执行单引号内的转义内容(单引号原本是原样引用的),这种方式会将引号内的一个或者多个[]转义后的八进制,十六进制值展开到ASCII或Unicode字符。
quote=$'\042'.
$*, $@
位置参数,这个在使用脚本文件的时候,在传递参数的时候会用到,两者都能返回调用脚本文件的所有参数
$* 是将所有参数作为一个整体返回(字符串)
$@是将每个参数作为单元返回一个参数列表
index=1 # Initialize count.
echo "Listing args with \"\$*\":"
for arg in "$*" # Doesn't work properly if "$*" isn't quoted.
do
echo "Arg #$index = $arg"
let "index+=1"
done # $* sees all arguments as single word.
echo "Entire arg list seen as single word."
echo
index=1 # Reset count.
# What happens if you forget to do this?
echo "Listing args with \"\$@\":"
for arg in "$@"
do
echo "Arg #$index = $arg"
let "index+=1"
done # $@ sees arguments as separate words.
echo "Arg list seen as separate words."
echo
index=1 # Reset count.
echo "Listing args with \$* (unquoted):"
for arg in $*
do
echo "Arg #$index = $arg"
let "index+=1"
done # Unquoted $* sees arguments as separate words.
echo "Arg list seen as separate words."
exit 0
代码输出:
$?
- 此变量值在使用的时候,返回的是最后一个命令、函数、或脚本的退出状态码值,如果没有错误则是0,如果为非0,则表示在此之前的最后一次执行有错误。 true 的返回码是0 false的返回码是非0
$$
- 进程ID变量,这个变量保存了运行当前脚本的进程ID值。
() 括号
- 命令组。
因为是在子shell内运行,因此在括号外面是没有办法获取括号内变量的值,但反过来,命令组内是可以获取到外面的值,这点有点像局部变量和全局变量的关系,在实作中,如果碰到要cd到子目录操作,并在操作完成后要返回到当前目录的时候,可以考虑使用subshell来处理;
a=123
( a=321; )
echo "a = $a" # a = 123
# "a" within parentheses acts like a local variable.
- 数组的初始化
Array=(element1 element2 element3)
{xxx,yyy,zzz,…}
- 在命令中可以用这种扩展来扩展参数列表
注意的一点是,这花括号扩展中不能有空格存在,如果确实有必要空格,则必须被转义或者使用引号来引用
echo \"{These,words,are,quoted}\" # " prefix and suffix
# "These" "words" "are" "quoted"
cat {file1,file2,file3} > combined_file
# Concatenates the files file1, file2, and file3 into combined_file.
cp file22.{txt,backup}
# Copies "file22.txt" to "file22.backup
{a..z}
- 列举字符
#!/bin/bash
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
# Echoes characters between a and z.
echo {0..3} # 0 1 2 3
# Echoes characters between 0 and 3.
base64_charset=( {A..Z} {a..z} {0..9} + / = )
# Initializing an array, using extended brace expansion.
# From vladz's "base64.sh" example script.
{} 花括号
- 代码块
这个是匿名函数,但是又与函数不同,在代码块里面的变量在代码块后面仍能访问。注意:花括号内侧需要有空格与语句分隔。
#!/bin/bash
a=123
{ a=321; }
echo "a = $a" # a = 321 (value inside code block)
# Thanks, S.C.
- {} 代码块里的内容可以通过IO重定向
#!/bin/bash
# Reading lines in /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
# Now, how do you parse the separate fields of each line?
# Hint: use awk, or . . .
# . . . Hans-Joerg Diers suggests using the "set" Bash builtin.
- 在xargs -i中的话,还可以作为文本的占位符,用以标记输出文本的位置。
#!/bin/bash
# copydir.sh
# Copy (verbose) all files in current directory ($PWD)
#+ to directory specified on command-line.
E_NOARGS=85
if [ -z "$1" ] # Exit if no argument given.
then
echo "Usage: `basename $0` directory-to-copy-to"
exit $E_NOARGS
fi
ls . | xargs -i -t cp ./{} $1
# ^^ ^^ ^^
# -t is "verbose" (output command-line to stderr) option.
# -i is "replace strings" option.
# {} is a placeholder for output text.
# This is similar to the use of a curly-bracket pair in "find."
#
# List the files in current directory (ls .),
#+ pass the output of "ls" as arguments to "xargs" (-i -t options),
#+ then copy (cp) these arguments ({}) to new directory ($1).
#
# The net result is the exact equivalent of
#+ cp * $1
#+ unless any of the filenames has embedded "whitespace" characters.
exit 0
{} \;
- 这个{}是表示路径名,现在接触到的情况看,好像只用在find命令里
find ~/ -name 'core*' -exec rm {} \;
# Removes all core dump files from user's home directory.
[ ] 中括号
测试的表示 Shell会测试在[]内的表达式
在数组的上下文中,表示数组元素,方括号内填上数组元素的位置就能获得对应位置的内容
Array[1]=xxx
echo ${Array[1]};
- 表示字符集的范围,在正表达式中,方括号表示该位置可以匹配的字符集范围。
"[xyz]" matches any one of the characters x, y, or z.
"[c-n]" matches any one of the characters in the range c to n.
"[B-Pk-y]" matches any one of the characters in the ranges B to P and k to y.
"[a-z0-9]" matches any single lowercase letter or any digit.
Combined sequences of bracketed characters match common word patterns. "[Yy][Ee][Ss]" matches yes, Yes, YES, yEs, and so forth. "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" matches any Social Security number.
"[^b-d]" matches any character except those in the range b to d. This is an instance of ^ negating(否定) or inverting the meaning of the following RE (taking on a role similar to ! in a different context).
[[ ]]
- 这个结构也是测试,测试[[]]之中的表达式(Shell的关键字)。这个比单中括号更能防止脚本里面的逻辑错误,比如:&&,||,<,>操作符能在一个[[]]里面测试通过,但是在[]却不能通过。[[]]里面没有文件名扩展(filename expansion)或是词分隔符(Word splitting),但是可以用参数扩展(Parameter expansion)和命令替换(command substitution)。不用文件名通配符和像空白这样的分隔符。注意,这里面如果出现了八进制,十六进制等,shell会自动执行转换比较。
# [[ Octal and hexadecimal evaluation ]]
# Thank you, Moritz Gronbach, for pointing this out.
decimal=15
octal=017 # = 15 (decimal)
hex=0x0f # = 15 (decimal)
if [ "$decimal" -eq "$octal" ]
then
echo "$decimal equals $octal"
else
echo "$decimal is not equal to $octal" # 15 is not equal to 017
fi # Doesn't evaluate within [ single brackets ]!
if [[ "$decimal" -eq "$octal" ]]
then
echo "$decimal equals $octal" # 15 equals 017
else
echo "$decimal is not equal to $octal"
fi # Evaluates within [[ double brackets ]]!
if [[ "$decimal" -eq "$hex" ]]
then
echo "$decimal equals $hex" # 15 equals 0x0f
else
echo "$decimal is not equal to $hex"
fi # [[ $hexadecimal ]] also evaluates!
$[ … ]
- 在方括号里面执行整数表达式
a=3
b=7
echo $[$a+$b] # 10
echo $[$a*$b] # 21
(( ))
- 功能和上面的 []差不多,但是需要注意的是, []是会返回里面表达式的值的,而(())只是执行,并不会返回值。两者执行后如果变量值发生变化,都会影响到后继代码的运行。可对变量赋值,可以对变量进行一目操作符操作,也可以是二目,三目操作符。
#!/bin/bash
# c-vars.sh
# Manipulating a variable, C-style, using the (( ... )) construct.
echo
(( a = 23 )) # Setting a value, C-style,
#+ with spaces on both sides of the "=".
echo "a (initial value) = $a" # 23
(( a++ )) # Post-increment 'a', C-style.
echo "a (after a++) = $a" # 24
(( a-- )) # Post-decrement 'a', C-style.
echo "a (after a--) = $a" # 23
(( ++a )) # Pre-increment 'a', C-style.
echo "a (after ++a) = $a" # 24
(( --a )) # Pre-decrement 'a', C-style.
echo "a (after --a) = $a" # 23
echo
echo
(( t = a<45?7:11 )) # C-style trinary operator.
# ^ ^ ^
echo "If a < 45, then t = 7, else t = 11." # a = 23
echo "t = $t " # t = 7
echo