【www.hj8828.com】Linux Shell常用技巧(一)

shell脚本(一)基础知识,shell脚本基础知识

shell

一、简介

1.作用:与内核进行交互

2.语言类型:解释性语言,给内核解释用

3.脚本中第一行内容:

#!/bin/bash                      
这是shell脚本的第一行内容,表示用bash这个解释器去解释下面的内容

#!/bin/sh                           
这也可以是shell脚本的第一行内容,表示用sh这个解释器去解释下面的内容

#!/usr/bin/env bash       
env表示使用相对路径,自动找bash解释器所在位置。可以解决不同版本的系统bash不一定在/usr/bin/bash这个路径下的问题

4.为了使脚本方便其他人阅读,一般会在开头加上作者、创建时间、邮箱、版本、描述等内容,可以使用以下设置快捷键的方法在脚本中增加这些信息

vim /etc/vimrc

map <F4> ms:call WESTOS()<cr>’s
function WESTOS()
        call
append(0,”######################################”)
        call append(1,”# Author     :vaon                   #”)
        call append(2,”# Create
Date:”.strftime(“%Y-%m-%d”).”             #”)
        call append(3,”# Email     
:[email protected]        
#”)
        call append(4,”# Version    :1.0                    #”)
        call append(5,”# Description:                       #”)
        call
append(6,”######################################”)
        call append(7,”                          “)
        call append(8,”#!/usr/bin/env bash”)
endfunction

#map表示影射–>按F4时调用(呼叫)WESTOS函数

#0代表第一行,1第二行…

#黄色部分strftime是一个系统自带的函数,表示显示当前时间   .是分隔符,表示这个函数与其他两段内容互不影响

#下面是设定函数的方法:

    Fucton 函数名()

    内容

    Endfunction

然后创建一个脚本使用F4键就会在脚本最前面自动加上以下内容:

二、基础知识

1.变量的声明${a}b

设定a=1

echo $a 会出现1,

但echo $ab就不会出现1b,因为系统把ab当成一个变量了。

可以echo ${a}b,会出现1b,把作为一个已定义的1

2.转义、弱引用、强引用

1)\表示转义

echo ###不会出现结果,但是加上 echo \#\#\#就会出现###

2)“”表示弱引用,也可以输出###

3)‘’表示强引用,可以输出###

4)强引用和弱引用的区别

例如 $  !  \  “  这些强引用会把他们当作普通内容打印到屏幕上

而弱引用会把他们当成系统变量,执行变量里的内容

还例如在弱引用中`hostname`表示执行hostname命令

而在强引用中表示输出`hostname`这个内容

3.diff、patch

1)diff

【1】.

[[email protected]
mnt]# cat file1
abcd
1234
[[email protected]
mnt]# cat file2
abcd
[[email protected]
mnt]# diff file1 file2
2d1
< 1234
#表示file1删除1234就和file2一样了

【2】.比较目录

diff -r 目录一 目录二

2)打补丁

建立hello文件:

vim hello

westos

建立hello.new文件:

vim hello.new

westos

456

安装自动更新工具包:

yum install patch -y

将hello.new与hello文件比较,多出的内容做成hello.path补丁包:

diff -u hello hello.new > hello.path

用path补丁包去更新hello文件:

patch hello hello.path

查看hello文件,已经被更新成和hello.new一样了:

cat hello

westos

456

注:如果patch后面加上-b参数表示在更新的同时备份原文件为hello.orig

4.grep

首先建立一个文件:

[[email protected]
mnt]# vim /mnt/passwd

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
hello
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
test:ROOT:test
test:test:root
test:root:test
test:roottest:test

1)查找包含root子段的行

[[email protected]
mnt]# grep root /mnt/passwd
root:x:0:0:root:/root:/bin/bash
test:test:root
test:root:test
test:roottest:test

2)查找包含root子段的行,不区分大小写

[[email protected]
mnt]# grep -i root /mnt/passwd
root:x:0:0:root:/root:/bin/bash
test:ROOT:test
test:test:root
test:root:test
test:roottest:test

3)只要root开头的

[[email protected]
mnt]# grep -i ^root /mnt/passwd
root:x:0:0:root:/root:/bin/bash

4)只要root结尾的

[[email protected]
mnt]# grep -i root$ /mnt/passwd
test:test:root

5)以root开头和结尾的行都不要。-E表示后面两个条件同时筛选,-v表示不要筛选出的行

[[email protected]
mnt]# grep -i root /mnt/passwd|grep -i -E “^root|root$” -v
test:ROOT:test
test:root:test
test:roottest:test

6)表示只要包含只有root子段的行,root前后只要有字母都不要,如roottest这行就不要

[[email protected]
mnt]# grep -i “\<root\>” /mnt/passwd|grep -i -E “^root|root$”
-v
test:ROOT:test
test:root:test
问题:

查看所有能登陆系统的用户

解答:

[[email protected]
mnt]# grep “\<bash\>” /etc/passwd
root:x:0:0:root:/root:/bin/bash
可见只有root能登陆
7)grep -n 表示显示搜索出的字符串所在行号

[[email protected]
mnt]# grep -n hello /mnt/passwd
4:hello

8)gep -n2
表示显示搜索出的行以及它的上面2行和下面2行,并且显示各自在文件中的行号

注:如果-n和2之间有空格则表示除了上面显示的内容还会在每行开头显示出文件名

[[email protected]
mnt]# grep -n2 hello /mnt/passwd
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:hello
5-mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
6-games:x:12:100:games:/usr/games:/sbin/nologin

9)grep -B2 表示显示搜索出的行以及这行的上两行内容
[[email protected]
mnt]# grep -B2 hello /mnt/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
hello
10)grep -A2 表示下两行

[[email protected]
mnt]# grep -A2 hello /mnt/passwd
hello
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
11)表示搜索/mnt目录下包含root字符的文件
[[email protected]
mnt]# grep -r hello /mnt/
/mnt/passwd:hello

5.cut

用法:cut -d 分隔符 -f 第几列 文件

-c指定字符

-d指定分隔符

-f指定第几列

cut -d : -f 2 /mnt/psswd     #以:为分隔符,显示passwd文件第二列

cut -d : -f 2,7 /mnt/psswd   #,表示第二和第七列,如果是-表示2到第7列

cut -c 3 /mnt/passwd      #显示第三列的字符,不使用分隔符

cut -c 1,3 /mnt/passwd     #显示一和三列的字符,不使用分隔符

题目:

显示eth0网卡的ip

解答:

[[email protected]
mnt]# ifconfig eth0|grep “\<inet\>”|cut -d ” ” -f 10
172.25.254.1

6.awk

-v表示给变量赋予内容:

[[email protected]
mnt]# name=hello
[[email protected]
mnt]# awk -F : -v name=$name ‘BEGIN {print name} {print $1}END {print
“end”}’ /mnt/passwd
hello
root
bin
daemon
hello
mail
games
test
test
test
test
end
7.sed

-i      #这个参数表示写入文件

sed ‘s/old/new/g’ passwd       #将passwd文件中的所有old字符替换为new

sed ‘s/old/new/g’ passwd       #将passwd文件中的所有old字符替换为new,并写入passwd文件

sed ‘2,5s/old/new/g’ passwd      #替换2到5行

sed ‘/adm/,/gdm/s/old/new/g’ passwd   #从adm字符一直到gdm字符的内容中将old替换为new

sed -e ‘s/old/new/g’ -e ‘s/old1/new1/g’ passwd  
#将old替换为new同时将old1替换为new1

sed 5d passwd    #删除第5行

sed 5p passwd    #复制第5行

sed -n 5p passwd    #只显示第5行

-p    #表示直接将 sed 的动作写在一个档案内, -f filename 则可以执行
filename 内的sed 动作

vim file

s/sbin/westos/g
s/nologin/linux/g

sed -f file passwd

题目:

将httpd服务端口改为8080

解答:

############################
# Author     :vaon                           #
# Create Date:2017-12-16             #
# Email     
:[email protected]      
#
############################

#!/bin/bash
PORT=`grep ^Listen /etc/httpd/conf/httpd.conf`
sed “s/$PORT/Listen $1/g” -i /etc/httpd/conf/httpd.conf
systemctl restart httpd

8.设置变量

1)临时设置(环境级)

在当前环境生效,当前环境关闭,变量失效

先看一个例子:

[[email protected]
mnt]# a=1
[[email protected]
mnt]# echo $a
1
[[email protected]
mnt]# vim test.sh
#!/bin/bash
echo $a
[[email protected]
mnt]# sh test.sh 

[[email protected]
mnt]#

#由于a=1是在当前使用的shell里面赋的值,当进入脚本执行时,脚本使用的是子shell,这个子shell中并没有设定a=1,所以结果为空

[[email protected]
mnt]# export a=1
[[email protected]
mnt]# sh test.sh
1

#可以临时设定a=1给所有shell,一旦登出就会失去这个临时设定

2)永久设置

【1】.系统级

对所有用户生效

[[email protected]
mnt]# vim /etc/profile

export a=1

[[email protected]
mnt]# source /etc/profile

[[email protected]
mnt]# logout
Connection to 172.25.254.1 closed.
[[email protected]
Desktop]# ssh
[email protected]
[email protected]’s
password:
Last login: Sat Dec 16 09:12:16 2017 from 172.25.254.10
[[email protected]
~]# cd /mnt/
[[email protected]
mnt]# sh test.sh
1

#这样所有shell都可以使用a=1这个变量,登出系统再登陆依然存在a=1

【2】.用户级

只针对配置过的用户生效,其他用户无法使用

vim /root/.bash_profile

export a=1

source /root/.bash_profile

现在a=1只对root用户生效

9.将脚本加到系统命令中去
[[email protected]
mnt]# vim /etc/profile

export PATH=$PATH:/mnt

注:这里同样存在系统级或用户级的设置,在这里使用的是系统级设置。如果只允许root可以设置/root/.bash_profile文件

[[email protected]
mnt]# source /etc/profile

[[email protected]
mnt]# chmod +x test.sh 

然后退出/mnt目录,直接把test.sh脚本当成系统命令去执行,发现也可以:

[[email protected]
mnt]# cd
[[email protected]
~]# test.sh
1
10.命令别名

1)使用别名

[[email protected]
~]# vim /etc/bashrc
alias kan=’cat’             #表示执行’kan’的时候相当于执行’cat’命令

[[email protected]
~]# source /etc/bashrc

查看别名列表:

[[email protected]
~]# alias

         …

alias kan=’cat’

         …

执行kan这个单词就相当于执行cat命令

[[email protected]
~]# kan /mnt/test.sh
######################################
# Author     :vaon                   #
# Create Date:2017-12-16             #
# Email     
:[email protected]        
#
######################################
                          
#!/bin/bash
echo $a
2)删除别名
删除/etc/bashrc中的alias kan=’cat’

然后在删除kan信息:

unalias kan

现在查看alias列表,里面已经没有kan的信息了

11.*和@区别

vim test.sh

#!/bin/bash
echo ‘$1 Is’ $1
echo ‘$2 Is’ $2
echo ‘$3 Is’ $3
echo ‘$* Is’ $*
echo ‘$# Is’ $#
echo
‘[email protected]
Is’
[email protected]
[[email protected]
mnt]# sh test.sh 1 2 3
$1 Is 1                                                  
#显示第1个字符
$2 Is 2                                                  
#显示第1个字符
$3 Is 3                                                  
#显示第1个字符
$* Is 1 2 3                                            
#显示所有字符
$# Is 3                                                  
#显示最后一个字符
[email protected]
Is 1 2 3                                           #显示所有字符
*和@都表示所有内容,但实际上一个是所有内容方到“”里面。而@是每个数据都加引号

$*   “1 2 3”

&@  “1” “2” “3”

12.shell脚本中函数的定义

READ()

{

        echo hello word

}

13.变量对比

1)test

2)[ ]

[[email protected]
mnt]# a=1
[[email protected]
mnt]# b=1
[[email protected]
mnt]# test “$a” == “$b” && echo yes || echo no
yes
[[email protected]
mnt]# [ “$a” == “$b” ] && echo yes || echo no
yes
3)[ 条件1 -a 条件2 ] 表示条件1和2都满足
4)[ 条件1 -o 条件2 ] 表示条件1和2任一个满足

5)[ 条件1 -eq 条件2 ]  等于

6)[ 条件1 -ne 条件2 ]  不等于

7)[ 条件1 -gt 条件2 ]  大于

8)[ 条件1 -ge 条件2 ]  大于等于

9)[ 条件1 -lt 条件2 ]  小于

10)[ 条件1 -le 条件2 ]  小于等于

[[email protected]
mnt]# [ “$a” -eq “$b” ] && echo yes || echo no
yes

11)[ -n ]   变量内容不为空

12)[ -z ]    变量内容为空

[[email protected]
mnt]# a=8
[[email protected]
mnt]# [ -n “$a” ] && echo yes || echo no
yes
[[email protected]
mnt]# [ -z “$a” ] && echo yes || echo no
no

13)[ -b ]  是否为块设备文件

14)[ -c ]  是否为字符设备文件

[[email protected]
mnt]# [ -b /dev/sda ] && echo yes || echo no
yes
[[email protected]
mnt]# [ -c /dev/vfio/vfio ] && echo yes || echo no
yes

15)[ -f ]  是否为常规文件

16)[ -S ]  是否为套接字文件

17)[ -L  ]  是否为链接文件

18)[ -d ]  是否为目录

19)[ -e ] 文件是否存在

20)[ -r ]  是否可读

21)[ -w ]  是否可写

22)[ -x ]  是否可执行

18)[ filename1 -nt filename2 ] 
如果 filename1 比 filename2 新,则为真

19)[ filename1 -ot filename2 ] 
如果 filename1 比 filename2 旧,则为真

[[email protected]
mnt]# touch file
[[email protected]
mnt]# [ /mnt/check_ip -ot file ] && echo yes || echo no
yes

题目:

显示输入的文件类型

解答:

#!/bin/bash
[ -e $1 ] && (
        [ -f $1 ] && echo “$1 Is File”
        [ -d $1 ] && echo “$1 Is Directory”
        [ -b $1 ] && echo “$1 Is Block File”
        [ -L $1 ] && echo “$1 Is Link”
        [ -S $1 ] && echo “$1 Is Socket”
)
14.四则运算

15.语句

case语句:
并发的去匹配所有条件,所有条件同一时间去配置,效率比if语句高

if语句是逐行去匹配,第一行不匹配再去匹配下一行,效率较低

exit 退出脚本。后面加数字1|0则表示退出后$?的值为1|0

break 退出循环

Linux正则表达式awk讲解

awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk常用来分段;

awk不用加任何参数就可以实现 + ? * .  | 这些特殊符号;

1、截取文档中的某个段
[[email protected]
~]# head -n2 passwd |awk -F: ‘{print $1}’
root
bin
[[email protected]
~]# head -n2 passwd |awk -F: ‘{print $0}’
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[[email protected]
~]# head -n2 passwd |awk -F: ‘{print $1,$3,$7}’
root 0 /bin/bash
bin 1 /sbin/nologin

-F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。
Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。

{ }内可以打印多个字段$1,$3,$7 打印第1、3、7段,中间用逗号隔开;

打印分段默认分隔符为空格,可以自定义分隔符,分隔符需要用冒号括起来;也可以OFS定义输出分隔符;
[[email protected]
~]# awk -F: ‘{print $3,$4}’ 1.txt |head -5
0 0
1 1
2 2
3 4
4 7
[[email protected]
~]# awk -F: ‘{print $3″:”$4}’ 1.txt |head -5
0:0
1:1
2:2
3:4
4:7
[[email protected]
~]# awk -F: ‘OFS=”#”{print $3,$4}’ 1.txt |head -5
0#0
1#1
2#2
3#4
4#7

[[email protected]
~]# head -n2 passwd |awk -F: ‘{print $1″#””@”$3″#”$7}’
root#@0#/bin/bash
bin#@1#/sbin/nologin

注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用 { }
括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用“”双引号括起来。

2、匹配字符或字符串
[[email protected]
~]# awk -F: ‘$1~/me/’ passwd 
games:x:12:100:games:/usr/games:/sbin/nologin
[[email protected]
~]# awk -F: ‘$1~/user/’ passwd 
user1:x:600:501::/home/user1:/bin/bash

可以让某个段去匹配,~
表示匹配的意思,以冒号分隔第一字段然后匹配//里的关键字;

[[email protected]
~]# awk -F: ‘/root/ {print $1,$3} /user/ {print $1,$3}’ passwd 
root 0
operator 11
ftp 14
saslauth 499
user1 600

awk还可以多次匹配,如上例全文匹配包含root关键词的行,再匹配包含user的行,打印所匹配的第1、3段。

3、条件操作符
判断第3个字段为0的
[[email protected]
~]# awk -F: ‘$3==”0″‘ passwd 
root:x:0:0:root:/root:/bin/bash
[[email protected]
~]# awk -F: ‘$3==10’ passwd 
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

判断第3个字段为10的并且打印该行的第7字段;

[[email protected]
~]# awk -F: ‘$3==10 {print $7}’ passwd 
/sbin/nologin
[[email protected]
~]# awk -F: ‘$3==”600″‘ passwd 
user1:x:600:501::/home/user1:/bin/bash

 

awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’
另外也有 >, ‘>=, ‘<, ‘<=, ‘!=
等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。

 

示例,双引号括起来认为是字符;加单引号和不加则认为是数字;
[[email protected]
~]# awk -F: ‘$3>”500″‘ passwd | sort -t: -k 3 -n 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
sshd:x:74:74:privilege-separated ssh:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:system message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:nobody:/:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash

[[email protected]
~]# awk -F: ‘$3>500’ passwd | sort -t: -k 3 -n 
user1:x:600:501::/home/user1:/bin/bash
[[email protected]
~]# awk -F: ‘$3>’500” passwd | sort -t: -k 3 -n 
user1:x:600:501::/home/user1:/bin/bash

 

!= 为不匹配,第7字段不等于/sbin/nologin的行,需要用双引号括起来。
[[email protected]
~]# awk -F: ‘$7!=”/sbin/nologin”‘ passwd 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
user1:x:600:501::/home/user1:/bin/bash
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash

 

除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较。

[[email protected]
~]# awk -F: ‘$3>”5″ && $3<“7″‘ passwd 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash

另外还可以使用 && “并且”和  || “或者” 的意思。
示例,打印第3段大于第4段,并且第7段为/bin/bash的行;
[[email protected]
~]# awk -F: ‘$3>$4 && $7==”/bin/bash”‘ passwd 
user1:x:600:501::/home/user1:/bin/bash

示例,打印第3段小于第4段,或者第7段为/bin/bash的行;
[[email protected]
~]# awk -F: ‘$3<$4 || $7==”/bin/bash”‘ passwd 
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:ftp user:/var/ftp:/sbin/nologin
user1:x:600:501::/home/user1:/bin/bash
mysql:x:27:27:mysql server:/var/lib/mysql:/bin/bash

4、awk的内置变量

awk常用的变量有:
NF :用分隔符分隔后一共有多少段
NR :行数
{print NR”:”NF}    列出行号,以冒号分隔,列出共有多少段;

[[email protected]
~]# head -5 passwd |awk -F: ‘{print NR”:”NF}’
1:7
2:7
3:7
4:7
5:7
[[email protected]
~]# head -5 passwd |awk -F: ‘{print NF}’
7
7
7
7
7
[[email protected]
~]# head -5 passwd |awk -F: ‘{print NR}’

[[email protected]
~]# head -5 passwd |awk -F: ‘{print $NF}’
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin

NF 表示是多少段,而$NF是最后一段的值,
而NR则是行号。5、awk中的数学运算awk还可以对各个段的值进行数学运算:12
[[email protected]
~]# awk -F: ‘{(tot=tot+$3)};END {print tot};’ passwd 
1720

这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的。

示例,if判断,如第一段的值为root,打印整行;
[[email protected]
~]# awk -F: ‘{if ($1==”root”) print $0}’ passwd 
root:x:0:0:root:/root:/bin/bash

示例,for循环,定义sum变量,i值为第3段的值;求第3段的和;

[[email protected]
~]# sum=0;for i in `awk -F: ‘{print $3}’ passwd`;do
sum=$[($sum+$i)];done;echo $sum
1720

    echo “Password2 = ” $password2

————————————–分割线

本文永久更新链接地址:

awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做…

   
有时,你会需要从文本文件里把几行字,多半是靠近开头或结尾的几行提取出来。如查看工作日志等操作。Linux
Shell提供head和tail两个命令来完成此项工作。见如下用例:

————————————–分割线

AWK简介及使用实例

AWK 简介和例子

Shell脚本之AWK文本编辑器语法

正则表达式中AWK的学习和使用

文本数据处理之AWK 图解

如何在Linux中使用awk命令

文本分析工具-awk 

    $                  
匹配紧接着的正则表达式,在行的结尾处。              
ab$,将匹配ab、cab等,但是不匹配abc。

   
这里需要进一步说明的是,使用cut命令还可以剪切以字符数量为标量的部分字符,该功能通过-c选项实现,其不能与-d选项共存。

    :x:3:4:adm:/var/adm:/sbin/nologin

   

    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    pulse:x:496:494:PulseAudio System
Daemon:/var/run/pulse:/sbin/nologin

    bin:x

    /> ./test_dev_tty

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    /> chmod +x trace_patial_command.sh

   
Linux系统提供了两个对Shell编程非常有用的特殊文件,/dev/null和/dev/tty。其中/dev/null将会丢掉所有写入它的数据,换句换说,当程序将数据写入到此文件时,会认为它已经成功完成写入数据的操作,但实际上什么事都没有做。如果你需要的是命令的退出状态,而非它的输出,此功能会非常有用,见如下Shell代码:

    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

    /> ./trace_patial_command.sh

        echo “Found”

    CTRL + D                           #退出命令行文件编辑状态

    read password2 < /dev/tty       #再读取一次以确认

   
如果使用者想查看不间断增长的日志(如服务程序输出的),可以使用tail的-f选项,这样可以让tail命令不会自动退出,必须通过CTRL+C命令强制退出,因此该选项不适合用于Shell脚本中,见如下用例:

    … …   

    /> chmod +x trace_all_command.sh

 

    /> vi test_dev_null.sh

    a:

    root:

    +(ERE)           和前面的星号相比,+匹配的是前面正则表达式的1-n   

三.    正则表达式基本语法描述:

    … …

    daem

    /> wc /etc/passwd /etc/group    #计算两个文件里的数据。

        echo “NOT Found”

   

    \<\>            
匹配单词的起始和结尾。                                         
\<read匹配readme,me\>匹配readme。

    root

 

    3:4:adm:/var/adm:/sbin/nologin

作者 Stephen_Liu

    *                  
匹配它之前的0-n个的单个字符。                          
a*b,将匹配ab、aab、aaab等。

    ERE                                                      *       *

五.    计算行数、字数以及字符数:

                        个实例。

                        在相同模式里。

    [:alnum:]      
匹配字母和数字字符。                                          
[[:alnum:]]ab$匹配1ab、aab。

    CTRL + D                             #退出命令行文件编辑状态

                        次;\{n,m\}表示重复n到m次。

                       
以将9个独立的子模式存储在单个模式中。匹配于子     
在任何数目的任何字符,如abcdab、abab等。

    |(ERE)          
匹配于|符号前后的正则表达式。                              
(ab|cd)匹配ab或cd。

    … …

  

    \                   
通常用于关闭其后续字符的特殊意义,恢复其原意。   
\(…\),这里的括号仅仅表示括号。

    ?(ERE)          
匹配前面正则表达式的0个或1个。                           
ab?仅匹配a或ab。

                       
首字符位置,如[]ab]或[-ab],如这两个字符同时存

    39   71  1933  /etc/passwd

 

    0:0:root:/root:/bin/bash

    [:xdigit:]       匹配十六进制数字。

    /> tail -f -n 5 my_server_log

    fi

    /> cat > trace_all_command.sh

    adm:adm

    2:2:daemon:/sbin:/sbin/nologin

    [:alpha:]       
匹配字母字符。                                                   
[[:alpha:]!]ab$匹配cab、dab和!ab。

 

    + wc -l                               #被跟踪的两条Shell命令

    if grep hello TestFile

    2nd echo

    echo 1st echo                     #将被打印输出的Shell命令

    正则Meta字符    
模式含义                                                                  
用例

    #!/bin/bash

    bin:bin

    if grep hello TestFile > /dev/null

    + echo 1st echo

    All Done