shell的小知识
1、#!
用于指定命令解释器,如果没有这行,shell脚本也可以运行,但是shell的内建命令就不能运行了,例如:[
2、变量赋值
变量赋值中能出现空格,例如(参加:一行中运行多个命令)
a =b,这句话会被解释成运行命令a,它的参数是=b
a= b,这句话会被解释成,设定环境变量a="",并运行命令b
3、一行中运行多个命令
我们通常在shell命令行中,一次输入一个命令来执行。其实一行中可以运行多个命令和给变量赋值。其中多个命令需要分号来分割,变量赋值只需要空格分割就行。
$ a=b ls;echo $a
4、调试手段echo
echo会将多个空格合并为一个,如果想得到原有输出,需要将引号。echo还可以打印转义字符,需要-e选项或$' '结构。例如
[whh@WebAppServer ~]$ echo a b c
a b c
[whh@WebAppServer ~]$ echo "a b c"
a b c
[whh@WebAppServer ~]$ echo -e "\n"
[whh@WebAppServer ~]$
5、test
每个命令都有一个退出码,if可以测试任何命令的退出码。例如:if ls ;then echo hello;fi 。let和 (( ))也有退出码,所不同的是,如果算数结果非零,则退出码反而是0。这里用0表示真,非零表示假,和C语言中的相反。为什么?因为我们写程序习惯返回0,表示函数或命令执行成功。
返回真的情况 if [ 0 ]; if [ 1 ]; if [ -1 ]; if [ xyz ]; if[ false ] 。
返回假的情况 if [ $xyz ]; if [ "$xyz" ]; if [ -n "$xyz" ] xyz变量未定义
if 和 then都是关键字,而关键字是一个表达式的开头。在一个表达式开始时,必须结束前一个表达式。所以if和then之间需要分号。
测试分整形和字符串形,这两类的比较操作符是不一样的
整形:-eq -ne -gt -ge -lt -le
字符:= != \> \< -n -z
文件测试形:-b -c -d -e -f -g -u -k -L -P -S -s -r -w -x
逻辑:-a -o ! 注:[ con1 -a con2 ] 与 [ con1 ] && [ con2 ] 相同
man test
6、双引号
字符串比较一定要加上双引号。整形比较也可以加上双引号,因为整型和字符串比较的操作符不一样,所以bash可以区分这是整型比较。
[whh@localhost sh]$ a="a b c"
[whh@localhost sh]$ [ -n $a ]
-bash: [: too many arguments
[whh@localhost sh]$ unset a
[whh@localhost sh]$ [ -n $a ] && echo a has value
a has value
在上面的例子中,如果变量中含有空格,则下面的测试中将会报错,因为变量展开后,为 [ -n a b c ] 。如果变量为空值,我们看到了,在这个测试中,测试结果与我们预期的不一样。我们期望 [ -n $a ] 将返回假,但是它返回了真。解决上面问题的办法是在变量引用时加上双引号。另外 [ -n "$a" ] 可以简写为 [ "$a" ]
7、数易做图算(man let)
let和(( ))支持数易做图算。在这两个结构中,变量引用和不引用都可以。
a=3 let "a=a+3" ; ((a++))
bash不支持浮点运算,所以let "a=a+1.3",将会出现语法错误。可以使用bc命令
8、参数检测
#!/bin/bash
:${xyza?}
echo hello
如果xyza变量没有设置,那么脚本第二行将报错,并终止脚本执行,你将看不到hello world输出。
9、变量替换
$! 最后一个在后台运行命令的PID
$@ 所有独立的命令行参数,这里面不包括$0,其实这正是我们所希望的。@在gdb中表示数组,数组都是分离的元素,这可以助记和$*的不同
$# 命令行参数个数,不包括$0
$$ 此shell的PID
$* 所有的命令行参数,注意和$@的区别。$*将所有的参数看出是一个参数。
$_ 上一个命令的最后一个参数
$? 上个程序的退出状态
$() 命令的结果
$(()) 数易做图算的结果
${} 如果要拼接字符串的话,需要这个
${#str} 字符串长度
${str#pattern} ${str##pattern} 删除str从开头最近的pattern或最远的pattern。助记:#在$钱,%在$后
${str%pattern} ${str%%pattern} 删除str从结尾最近的pattern或最远的pattern
${str/pattern/replace} ${str//pattern/replace} 删除或替换pattern成replace。//表示全局
内建变量:BASH UID PPID HOME HOSTNAME HOSTYPE ...
$RANDOM:随机数产生器
10、循环分支
if [ cond ] ; then
cmd1
else
cmd2
fi
for i in arg1 arg2 arg3
do
cmd
done
for (( i=0; i<10; i++ ))
do command
done
while [ condition ];do
done
case i in
a | 1) cmd1;;
b) cmd2;;
esac
select i in arg1 arg2 arg3
do
cmd
break
done
11、外部命令
m4 flex bison: 宏处理,词法及语法分析器
expr 通用表达式,完成数易做图算,字符串运算,比较和逻辑
eval 评估,对它后面的变量进行两次扩展,并运行其中的命令
last 用户的登录信息
stty 修改终端设置
script 对键盘操作进行记录
tee 三通管道
which 定位命令
type 定位命令类型
lsof 列出所有打开的文件
nmap 端口扫描器
nc 也是一个网络诊断工具
strace 跟踪系统调用及信号的调试工具
stat 显示文件状态
fuser 取得正在存取某个文件的进程IP
12、I/O重定向
1>filename 1>>filename 标准输出重定向/追加
2>filename 2>>filename 标准出错重定向
&>filename 标志输出和出错都重定向
i>&j 重定向文件描述符i 到 j. 例如 2>&1
<FILENAME 0<FILENAME 从FILENAME中接受标准输入
j <>FILENAME 打开文件FILENAME,并分配文件描述符j给它
87 echo 1234567890 > File # 写字符串到"File".
88 exec 3<> File # 打开"File"并且给它分配 fd 3.
89 read -n 4 <&3 # 只读 4 个字符.
90 echo -n . >&3 # 写一个小数点.
91 exec 3>&- # 关闭 fd 3.
n<&- 0<&- 关闭输入文件描述符n
n>&- 1>&- 关闭输出文件描述符n
13、here document
cmd <<LIMITSTRING
doc1
doc2
LIMITSTRING #LIMITSTRING必须打头写
14、数组
声明 declar -a var
初始化 var1=(a b c) var1=("${var1[@]}" "new") var2[0]=0 var2[1]=1 var2[${#var2[*]}]="new" a=(/dev/*) a=([0]="h" [2]="j")
遍历数组 n=${#a[@]} for (( i=0; i<n; i++ )) ; do cmd; done
15、显示彩色文本
echo -e '\E[COLOR1;COLOR2mSome text goes here.'
"\E[" 开始转义序列. 分号分隔的数值"COLOR1" 和 "COLOR2" 指定前景色和背景色, 数值和
色彩的对应参见下面的表格. (数值的顺序不是有关系的,因为前景色和背景色数值都落在不
重叠的范围里.) "m"终止该转义序列, 然后文本以结束的转义指定的属性显示.
也要注意到用单引号引用了 echo -e 后面的余下命令序列.
下表的数值是在 rxvt 终端运行的结果. 具体效果可能在其他的各种终端上不一样.
table 33-1. 转义序列中数值和彩色的对应
 
补充:综合编程 , 其他综合 ,