第一章:shell基础
●umask --查看当前用户创建文件或文件夹时的默认权限
eg:
[test@szbirdora 1]$umask
0002
[test@szbirdora 1]$ls -lh
-rw-rw-r-- test test myfile
drwxrwxr-x test test 1
上面的例子中我们看到由test默认创建的文件myfile和文件夹1的权限分别为664,775.而通过umask查到的默认权限为0002.所以可以推断出umask的计算算法为:
umask file directory
0 6 7
1 5 6
2 4 5
3 3 4
4 2 3
5 1 2
6 0 1
7 0 0
●连接ln
硬连接 ln sourcefile targetfile 连接后的target文件大小和source文件一样
软连接 ln -s sourcefile targetfile 类似于windows的快捷方式
●shell script 基本结构
#!/bin/bash --------bash shell开头必须部分
# description --------注释部分(可有可无,为了阅读方便最好加以说明)
variable name=value ---------变量部分,声明变量,赋值
control segment ---------流程控制结构,如判断、循环、顺序
eg.
helloworld.sh
#!/bin/bash
# This is a helloworld shell script
printchar = "hello world"
echo $printchar
[test@szbirdora 1]$sh helloworld.sh
hello world
●shell 特性
①别名 alias eg. alias ll = “ls -l”
②管道 a |b 将a命令的输出作为b命令的输入
eg.
ls |sort 将ls列举的项排序
③命令替换 a `b` 将b命令的输出作为a命令的输入
eg.
ls `cat myfile` 列举出cat myfile的输出项
④后台运行 nohup command& 可通过jobs -l查看后台运行的脚本
⑤重定向 >,
PWD --当前目录
MAILCHECK --每隔多少秒检查是否有新邮件
[test@szbirdora 1]$ echo $MAILCHECK
60
SHELL
MANPATH --帮助文档位置
TERMINFO --终端信息
●特殊变量
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 传递到脚本的参数列表,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态,0表示没有错误,其他表示有错误
eg.
#!/bin/bash
#parm
echo "this is shellname: $0"
echo "this is parm1 : $1"
echo "this is parm2 : $2"
echo "show parm number : $#"
echo "show parm list : $*"
echo "show process id: $$"
echo "show precomm stat: $?"
[test@szbirdora 1]$ sh parm.sh a b
this is shellname: parm.sh
this is parm1 : a
this is parm2 : b
show parm number : 2
show parm list : a b
show process id: 24544
show precomm stat: 0
●影响变量的命令
declare 设置或显示变量
-f 只显示函数名
-r 创建只读变量
-x 创建转出变量
-i 创建整数变量
使用+替代-,可以颠倒选项的含义
export
-p 显示全部全局变量
shift[n] 移动位置变量,调整位置变量,使$3赋予$2,使$2赋予$1 n 前移n
typeset 和declare同义
注意:双引号不能解析$,\,`三个字符,所以在双引号中可以引用变量、转义字符、替换变量
单引号可以解析,所以单引号中引用变量等无效
[test@szbirdora 1]$ echo "$test"
test
[test@szbirdora 1]$ echo '$test'
$test
●运算符类型
⒈按位运算符
~ 取反
右移运算符
& 与
| 或
^ 异或
$[ ] 表示形式告诉shell对方括号中表达式求值 $[a+b]
2.逻辑运算符
&&
||
>,mylogfile.txt
[test@szbirdora ~]$ sh echod.sh
this echo's 3 newlne
OK
this is echo's 3 ewline\n\n\n
上面可以看到有-e则可以解析转移字符,没有不能解析。echo空输出为空
2.read 可以从键盘或文件的某一行文本中读入信息,并将其赋给一个变量
read variable1 variable2
eg.
#!/bin/bash
#readname
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo "this name is $firstname $lastname"
3.cat 显示文件的内容,创建内容,还可以显示控制字符
cat [options]filename1 filename2
-v 显示控制字符(Windows文件)
cat命令不会分页显示,要分页可以采用more、less
4.管道|
5.tee 把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中,一般与管道合用
tee [options] files
-a 在文件中追加
eg.
[test@szbirdora 1]$ echo |tee myfile
[test@szbirdora 1]$ cat myfile
将myfile文件置空
6.文件重定向
command>filename ---覆盖输出
command>>filename ---追加输出
command>filename>&1 ---把标准输出和标准错误重定向
command>myfile
[test@szbirdora 1]$ cat myfile
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 3.3G 16G 18% /
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda2 79G 17G 59G 23% /u01
/dev/sda4 28G 3.9G 22G 15% /u02
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 3.3G 16G 18% /
none 2.0G 0 2.0G 0% /dev/shm
/dev/sda2 79G 17G 59G 23% /u01
/dev/sda4 28G 3.9G 22G 15% /u02
[test@szbirdora 1]$ cat >>myfile Hubei
> Suizhou
> exit
[test@szbirdora 1]$ cat myfile
China
Hubei
Suizhou
7.exec 可以用来替代当前shell。现有任何环境变量都会清除
第四章 控制流结构
1.if语句
if 条件1
then
命令1
elif 条件2
then
命令2
else
命令3
fi
------------------
if 条件
then 命令
fi
eg:
#!/bin/bash
#if test
#this is a comment line
if [ "10" -lt "12" ];then
#yes 10 is less than 12
echo "yes,10 is less than 12"
else
echo "no"
fi
注意:if语句必须以fi终止
"10" 前一个空格,“12”后也有一个空格。这个条件都是通过test命令来指定。条件表达为test expression或者[expression]
条件表达式中的比较函数
man test
NAME
test - check file types and compare values
SYNOPSIS
test EXPRESSION
[ EXPRESSION ]
[ OPTION
DESCRIPTION
Exit with the status determined by EXPRESSION.
--help display this help and exit
--version
output version information and exit
EXPRESSION is true or false and sets exit status. It is one of:
( EXPRESSION )
EXPRESSION is true
! EXPRESSION
EXPRESSION is false
EXPRESSION1 -a EXPRESSION2
both EXPRESSION1 and EXPRESSION2 are true
EXPRESSION1 -o EXPRESSION2
either EXPRESSION1 or EXPRESSION2 is true
[-n] STRING
the length of STRING is nonzero
-z STRING
the length of STRING is zero
STRING1 = STRING2
the strings are equal
STRING1 != STRING2
the strings are not equal
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
FILE1 -ef FILE2
FILE1 and FILE2 have the same device and inode numbers
FILE1 -nt FILE2
FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2
FILE1 is older than FILE2
-b FILE
FILE exists and is block special
-c FILE
FILE exists and is character special
-d FILE
FILE exists and is a directory
-e FILE
FILE exists
-f FILE
FILE exists and is a regular file
-g FILE
FILE exists and is set-group-ID
-h FILE
FILE exists and is a symbolic link (same as -L)
-G FILE
FILE exists and is owned by the effective group ID
-k FILE
FILE exists and has its sticky bit set
-L FILE
FILE exists and is a symbolic link (same as -h)
-O FILE
FILE exists and is owned by the effective user ID
-p FILE
FILE exists and is a named pipe
-r FILE
FILE exists and is readable
-s FILE
FILE exists and has a size greater than zero
-S FILE
FILE exists and is a socket
-t [FD]
file descriptor FD (stdout by default) is opened on a terminal
-u FILE
FILE exists and its set-user-ID bit is set
-w FILE
FILE exists and is writable
-x FILE
FILE exists and is executable
eg.
#!/bin/bash
#if test
#this is a comment line
echo "Enter your filename:"
read myfile
if [ -e $myfile ]
then
if [ -s $myfile ];then
echo "$myfile exist and size greater than zero"
else
echo "$myfile exist but size is zero"
fi
else
echo "file no exist"
fi
[test@szbirdora 1]$ sh iftest.sh
Enter your filename:
11
11 exist but size is zero
2.case语句
case语句为多选择语句。
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
eg.
#!/bin/bash
#case select
echo -n "enter a number from 1 to 3:"
read ans
case $ans in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "`basename $0`:this is not between 1 and 3">&2
exit;
;;
esac
3.for 循环
for循环一般格式:
for 变量名 in 列表 (列表以空格作为分割)
do
命令1
命令2
done
eg:
#!/bin/bash
#forlist1
for loop in 1 2 3 4 5
do
echo $loop
done
4.until循环
until 条件
do
命令1
命令2
...
done
条件测试发生在循环末尾,所以循环至少可以执行一次。
5.
while循环
while 命令 (可以是一个命令也可以是多个,做条件测试)
do
命令1
命令2
...
done
注意:如果从文件中读入变量 THE CHARACTER B IS BEST\
> *******************************' myfile
a
THE CHARACTER B IS BEST
*******************************
b
c
d
e
下一个:n 从一个文件中读文本下一行,并附加在下一行
退出命令 q 打印多少行后退出
eg.
[test@szbirdora 1]$ sed '3q' myfile
a alert
b best
c cook
sed script:
sed -f scriptfile myfile
5.awk介绍
awk可从文件或字符串值基于指定规则浏览和抽取信息
awk三种调用方式:
1.命令行方式
awk [-F field-sperator]'pattern{active}' input-files
awk [-F field-sperator]'command' input-files
awk脚本
所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解析器作为脚本的首行,以便通过键入脚本名称来调用。
awk命令插入一个单独文件
awk -f awk-script-file input-files
awk脚本由模式和动作组成
分隔符、域、记录
注意这里的$1,$2是域与位置变量$1,$2不一样。$0文件中的所有记录
eg:
awk '{print $0}' myfile
awk 'BEGIN {print "IP DATE ----"}{print $1"\t"$4}END{print "end-of -report"}
[test@szbirdora 1]$ df |awk '$1!~"dev"'|grep -v Filesystem
none 1992400 0 1992400 0% /dev/shm
[test@szbirdora 1]$ df |awk '{if ($1=="/dev/sda1") print $0}'
/dev/sda1 20641788 3367972 16225176 18% /
[test@szbirdora shelltest]$ cat employee
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
[test@szbirdora shelltest]$ awk '/[Aa]dams/' employee
Mary Adams 5346 11/4/63 28765
[test@szbirdora shelltest]$ sed -n '/[Aa]dams/p' employee
Mary Adams 5346 11/4/63 28765
[test@szbirdora shelltest]$ grep '[Aa]dams' employee
Mary Adams 5346 11/4/63 28765
三种命令方式下,使用模式匹配查询
[test@szbirdora shelltest]$ awk '{print $1}' employee
Tom
Mary
Sally
Billy
打印文件第一列
[test@szbirdora shelltest]$ awk '/Sally/{print $1"\t"$2}' employee
Sally Chang
打印匹配Sally的行的第一列和第二列
[test@szbirdora shelltest]$ df |awk '$4>20884623'
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 82567220 17488436 60884616 23% /u01
/dev/sda4 28494620 4589172 22457992 17% /u02
打印df输出第四列大于××的行
格式输出:
打印函数—
[test@szbirdora shelltest]$ date
Mon Mar 10 15:15:47 CST 2008
[test@szbirdora shelltest]$ date |awk '{print "Month:" $2"\nYear:" $6}'
Month:Mar
Year:2008
[test@szbirdora shelltest]$ awk '/Sally/{print "\t\tHave a nice day,"$1"\t"$2}' employee
Have a nice day,Sally Chang
printf函数
[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%-10s|\n",$1}'
|LINUX |
[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%10s|\n",$1}'
| LINUX|
~匹配符
[test@szbirdora shelltest]$ awk '$1~/Tom/{print $1,$2}' employee
Tom Jones
awk 给表达式赋值
关系运算符:
大于
== 等于
!= 不等于
>= 大于等于
$2) ? $1:$2;print max}' filename
运算符
+,-,*,/,%,^,&&,||,!
[test@szbirdora shelltest]$ cat /etc/passwd |awk -F: '\
NF!=7{\
printf("line %d does not have 7 fields:%s\n",NR,$0)}\
$1!~/[A-Za-z0-9]/{printf("line %d,nonalphanumberic user id:%s\n",NR,$0)}\
$2=="*"{printf("line %d,no password:%s\n",NR,$0)}'
awk编程
递增操作符 x++,++x
递减操作符 x--,--x
BEGIN模块
BEGIN模块后面紧跟着动作块,在读入文件前执行。通常被用来改变内建变量的值,如:FS\RS\OFS,初始化变量的值和打印输出标题。
[test@szbirdora shelltest]$ awk 'BEGIN{print "HELLO WORLD"}'
HELLO WORLD
[test@szbirdora shelltest]$ awk 'BEGIN{print "---------LIST---------"}{print}END{print "------END--------"}' donors
---------LIST---------
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50
Archie McNichol:(206) 548-1348:250:100:175
Jody Savage:(206) 548-1278:15:188:150
Guy Quigley:(916) 343-6410:250:100:175
Dan Savage:(406) 298-7744:450:300:275
Nancy McNeil:(206) 548-1278:250:80:75
John Goldenrod:(916) 348-4278:250:100:175
Chet Main:(510) 548-5258:50:95:135
Tom Savage:(408) 926-3456:250:168:200
Elizabeth Stachelin:(916) 440-1763:175:75:300
------END--------
重定向和管道
输出重定向
awk输出重定向到一个文件需要使用输出重定向符,输出文件名需要用双引号括起来。
[test@szbirdora shelltest]$ awk -F: '{print $1,$2>"note"}' donors
[test@szbirdora shelltest]$ cat note
Mike Harrington (510) 548-1278
Christian Dobbins (408) 538-2358
Susan Dalsass (206) 654-6279
Archie McNichol (206) 548-1348
Jody Savage (206) 548-1278
Guy Quigley (916) 343-6410
Dan Savage (406) 298-7744
Nancy McNeil (206) 548-1278
John Goldenrod (916) 348-4278
Chet Main (510) 548-5258
Tom Savage (408) 926-3456
Elizabeth Stachelin (916) 440-1763
输入重定向
getline函数
[test@szbirdora shelltest]$ awk 'BEGIN{"date +%Y"|getline d;print d}'
2008
[test@szbirdora shelltest]$ awk -F"[ :]" 'BEGIN{printf "What is your name?";\
getline name250){printf "%-2s%13s\n",$1,"-----------good partman"}else{print $1}}' donors
循环语句
[test@szbirdora shelltest]$ awk -F: '{i=1;while(i&1 ---把标准输出和标准错误重定向
command /dev/tty
done >temp$$
mv temp$$ $1
[test@szbirdora 1]$ sh loopred testmv
Processing file testmv.....
Process finish,total line number is 19
[test@szbirdora 1]$ vi testmv
1 /u01/test
2 /u01/test/1
3 /u01/test/1/11
4 /u01/test/1/forlist.sh
5 /u01/test/1/optgets.sh
6 /u01/test/1/whiletest.sh
7 /u01/test/1/func.sh
8 /u01/test/1/helloworld.sh
9 /u01/test/1/df.out
10 /u01/test/1/nullfile.txt
11 /u01/test/1/iftest.sh
12 /u01/test/1/myfile
13 /u01/test/1/opt2.sh
14 /u01/test/1/0
15 /u01/test/1/case.sh
16 /u01/test/1/nohup.out
17 /u01/test/1/hellfun.sh
18 /u01/test/1/parm.sh
19 /u01/test/1/test
15。在done后面加&使循环在后台运行,程序继续执行。
16.在函数内可以使用local定义本地变量,local variable。
17.陷阱信号 trap --当一个信号发出传递给进程时,进程进行相关操作,信号包括中断等
trap ‘command;command’ signal-num #trap设置时执行命令
trap “command;command” signal-num #信号到达时执行命令
eg:
[root@linux2 ~]# trap "echo -e 'hello world\n';ls -lh" 2
[root@linux2 ~]# hello world ---ctrl+c
total 100K
-rw-r--r-- 1 root root 1.4K Nov 14 16:53 anaconda-ks.cfg
drwxr-xr-x 2 root root 4.0K Nov 23 13:11 Desktop
-rw-r--r-- 1 root root 53K Nov 14 16:53 install.log
-rw-r--r-- 1 root root 4.9K Nov 14 16:53 install.log.syslog
drwxr-xr-x 2 root root 4.0K Nov 22 13:03 vmware