$ cd `dirname $0` 和PWD%} 显示当前目录名称
${#var} 替换为变量字符个数
特殊变量
$ 当前SHELL的PID
? 前一个命令的退出状态
! 后台执行的上一个工作的PID
读取用户输入
read 从终端读取输入存入内置变量REPLY
read var 从终端读取输入存入变量var
read first .. last 从终端读取多个变量依次存入,若输入较多,则最后一个变量成为包含多个值的字串
read -a array 从终端读取多个值存入数组中
read -p pmtstring var 向终端输出提示串,然后读入输入到var中
read -r line 读取一行,并允许/
变量类型转换
如果变量在声明时没确定类型,则变量根据赋值情况可以动态转换类型,但如果声明时变量类型已经确定,若赋值为其他类型,将导致原有数据丢失或出错。除非重新声明类型。
对于整数类型的变量,则在命令行支持算法扩展,如num=3*4,支持"",不支持空格。
进制
var=16#abc var为16进制数abc
输出
printf "The number is %.2f/n" 100
echo -ne "hello/nworld/n" -e 表示需要解析转义字符,-n 表示不自动添加换行符
位置参数
$0 1-0 ${10}
$# 求值位置参数个数
$* 求值所有位置参数
"$*"
$@
"$@"
引用
() 命令组,创建子SHELL执行
{} 命令组,不创建子SHELL
' ' 保护所有的元字符不被解析,想打印',必须放在双引号内,或者使用/转义
" " 只允许变量和命令替换,保护其余的元字符不被解析
命令替换
`cmd`
$(cmd)
二者结果都是一个字符串,如果加"",则保留换行,否则丢失换行。
数学表达式扩展
$[ exp ]
$(( exp ))
f
数组
declare -a array=(item1 item2 ...)
数组元素的引用 ${array[i]}
引用整个数组 ${array[*]}
unset array
函数定义
function f()
{
cmd;cmd;
}
I/O重定向
find . name /*.c print > foundit 2>&1
命令行参数
set可用来设置位置参数,使用set --将清除所有位置参数
$*与$@的区别只在于" "时,当$*放在""内时,参数表成为单个字符串,而$@放在""内时,每个参数都被引号括住。
表达式
评估表达式
expr $[3+4] $[ 3+4 ] $(( 3+4 ))
let算术扩展
let i=i+1 支持任何C类型的运算符,但只支持整形数运算
bash不支持小数运行,因此需要在bc或者awk中进行相应的运行,再把结果回。由于bash没有浮点型,所以小数是以字符串表示。
测试表达式
测试可以使用test或者单纯的[ expr1 cmp expr2],结果保存于?变量中,即test与[]等价
字符串测试
[ str1 = str2 ] str1与str2相同或==
[ str1 != str2 ] st1与str2不相同
[ str ] str非空
[ -z str ] str的长度为0
[ -n str ] str的长度非0
[ -l str ] str的长度
[ str1 -a str2 ] and
-o or
! not
复合条件测试
[[ p1 && p2 ]] p1与p2均为真
[[ p1 || p2 ]]
[[ !p2 ]]
整数测试
[ num1 -eq num2 ]
[ numb1 -ne num2 ]
gt ge lt le
文件属性测试
[ file1 nt file2 ] 文件1比文件2新
[ file1 ot file2 ]
[ file1 ef file2 ]
[-d file] file为目录
-b -c -p -L -S 块文件,字符文件,管道,链接,socket
-e -f 文件存在,常规文件
-G 文件存在且拥有有效GID
-O 文件存在且拥有有效UID
-g 设置GID
-k 设置stick位
-r -w -x 文件可读,可写,可执行的
-s 文件大小非0
-t 文件fd在终端打开
-u setUID位设置
测试表达可以与let的运算扩展及(( ))中的C型运算扩展是等价的,后者也许更容易理解,C-like。
条件控制
if command
then
command
command
fi
if test expression
then
command
fi
if [ string/numeric expression ] then
command
fi
if [[ string expression ]] then
command
fi
if (( numeric expression ))
if command
then
command(s)
else
command(s)
fi
if command
then
command(s)
elif command
then
commands(s)
elif command
then
command(s)
else
command(s)
fi
空命令 :
分支跳转
case variable in
value1)
command(s)
;;
value2)
command(s)
;;
*)
command(s)
;;
esac
循环
for variable in word_list
do
command(s)
done
while condition
do
command(s)
done
until command
do
command(s)
done
构建菜单的select
select program in 'ls -F' pwd date
do
$program
done
中断循环
break [n] 从第n层循环中跳出
continue [n] 继续第n层循环
捕获信号
信号列表
1) SIGHUP 9) SIGKILL 17) SIGCHLD 25) SIGXFSZ
2) SIGINT 10) SIGUSR1 18) SIGCONT 26) SIGVTALRM
3) SIGQUIT 11) SIGSEGV 19) SIGSTOP 27) SIGPROF
4) SIGILL 12) SIGUSR2 20) SIGTSTP 28) SIGWINCH
5) SIGTRAP 13) SIGPIPE 21) SIGTTIN 29) SIGIO
6) SIGABRT 14) SIGALRM 22) SIGTTOU 30) SIGPWR
7) SIGBUS 15) SIGTERM 23) SIGURG
8) SIGFPE 16) SIGSTKFLT 24) SIGXCPU
trap 'command; command' signal-number-list
trap 'command; command' signal-name-list 处理信号,当收到singal-list中的信号后,执行 ''中的命令
trap singal 重置信号处理函数
trap 列出已经设置信号处理
调试脚本
bash -x script 显示命令执行过程,及结果
bash -v script 显示脚本中的各行
bash -n script 解释但不执行
附录:
常用命令
script myfile 将终端交互信息保存在myfile中,使用control+d退出
fuser -n tcp 22 获得打开tcp 22的进程
lsof 获得进程打开的文件
- $(cd `dirname $0`; pwd)
在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的。因为他返回当前路径的"."。这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个目录来定位所要运行程序的相对位置。
- declare
+/-:"-"可用来指定变量的属性,"+"则是取消变量所设的属性; -f:仅显示函数; r:将变量设置为只读; x:指定的变量会成为环境变量,可供shell以外的程序来使用; i:[设置值]可以是数值,字符串或运算式。
declare命令用于声明和显示已存在的shell变量。当不提供变量名参数时显示所有shell变量。declare命令若不带任何参数选项,则会显示所有shell变量及其值。declare的功能与typeset命令的功能是相同的。
- if [ "$#" -ne "8" ]; then
$# 表示提供到shell脚本或者函数的参数总数;
$1 表示第一个参数。
-ne 表示 不等于
另外:
整数比较
-eq 等于,如:if ["$a" -eq "$b" ]
-ne 不等于,如:if ["$a" -ne "$b" ]
-gt 大于,如:if ["$a" -gt "$b" ]
-ge 大于等于,如:if ["$a" -ge "$b" ]
-lt 小于,如:if ["$a" -lt "$b" ]
-le 小于等于,如:if ["$a" -le "$b" ]
< 小于(需要双括号),如:(("$a" < "$b"))
<= 小于等于(需要双括号),如:(("$a" <= "$b"))
> 大于(需要双括号),如:(("$a" > "$b"))
>= 大于等于(需要双括号),如:(("$a" >= "$b"))
另外:$?是shell变量,表示"最后一次执行命令"的退出状态.0为成功,非0为失败.
basename命令
语法:basename string [suffix]
用于返回一个字符串的基本文件名称
basename命令读取string参数,删除以 / 结尾的前缀以及任何指定的suffix参数,并将剩余的基本文件名称写至标准输出。
basename命令应用以下创建基本文件名称的规则:
1· 如果 String 参数是 //(双斜杠) 或如果 String 参数包含的都是斜杠字符,则将字符串更改为单个 /(斜杠)。跳过步骤 2 到 4。
从指定字符串除去任何拖尾的 / 字符。
2· 如果在 String 参数中剩余任何 / 字符,则除去字符串的前缀直到(包含)最后一个 / 字符。
3· 如果指定 Suffix 参数,且它和字符串中的剩余的字符相同,则不修改此字符串。例如,输入:
# basename /u/dee/desktop/cns.boo cns.boo
结果是:
cns.boo
如果指定 Suffix 参数,且它和字符串中所有字符都不相同,但和字符串的后缀相同,则除去指定后缀。例如,输入:
# basename /u/dee/desktop/cns.boo .boo
结果是:
cns
不能在字符串中查找到指定的后缀不作为错误处理。
示例
(1)要显示一个 shell 变量的基本名称,请输入:
basename $WORKFILE
此命令显示指定给 shell 变量 WORKFILE 的值的基本名称。如果 WORKFILE 变量的值是 /home/jim/program.c 文件,则此命令显示 program.c
# basename /usr/bin/sort
# sort
(2)要构造一个和另一个文件名称相同(除了后缀)的文件名称,请输入:
OFILE=`basename $1 .c`.o
此命令指定给 OFILE 文件第一个位置上的参数($1)的值,但它的 .c 后缀更改至 .o。如果 $1 是 /home/jim/program.c 文件,则 OFILE 成为 program.o。因为 program.o 仅是一个基本文件名称,它标识在当前目录中的文件。
注:`(重音符号)指定命令替换。
dirname命令
用途说明
dirname命令可以取给定路径的目录部分(strip non-directory suffix from file name)。这个命令很少直接在shell命令行中使用,我一般把它用在shell脚本中,用于取得脚本文件所在目录,然后将当前目录切换过去。根据手册页上说的“Print NAME with its trailing /component removed; if NAME contains no /’s, output ‘.’ (meaning the current directory).”,似乎说“取给定路径的目录部分” 并不能很准确的概括dirname命令的用途。Linux下还有一个命令是basename,它与dirname相反,是取得文件名称部分。
常用参数
无。
使用示例
示例一 来自手册页的例子
[root@qzt196 ~]# dirname /usr/bin/sort
/usr/bin
[root@qzt196 ~]# dirname stdio.h
.
[root@qzt196 ~]#
示例二
[root@qzt196 ~]# dirname /usr/bin
/usr
[root@qzt196 ~]# dirname /usr/bin/
/usr