2018-06-01课堂笔记

Linux Shell基础(下)

目录

一、shell特殊符号cut命令
二、cut、sort、wc、uniq命令
三、tee、tr、split命令
四、简易审计系统
五、fork, exec, source三者执行shell脚本的区别


一、Shell特殊符号

字符 用途
换行符 启动命令的执行
; 分隔命令
( ) 通过子shell或标示函数执行命令分组
& 将命令放到后台执行
| 将前一个命令的输出发送给其后的命令(管道)
> 标准输也重定向
>> 标准输出追加重定向
< 标准输入重定向
<< Here文档
* 模糊文件引用中的零个或多个字符组成的串
? 模糊文件引用中的任意单个字符
\ 引用后面的字符
‘ (单引号) 引用字符串,阻止所有替换
“ (双引号) 引用字符串,只允许变量替换和命令替换
``(反引号) 命令替换
[ ] 模糊引用中的字符类别
$ 引用某个变量
.(内置句点) 执行命令(只在句首)
# 开始一行注释
{} 封装函数体
:(内置空串) 返回True
&&(逻辑与) 只有左边的命令成功(返回值是0),才会执行右边的命令
| | (逻辑或) 只有左边的命令失败(返回值是非0),才会执行右边的命令
!(逻辑非) 反传命令的退出状态值
$( ) 执行命令替换(推荐)
[ ] 计算算术表达式的值


//分号(;)将多条命令放在同一行
[root@lanquark demo]# ls;cat err.txt
1.txt  2.txt  3.txt  err.txt  f1.txt  f2.txt  ls.txt  temp  txt
ls: cannot access bb.txt: No such file or directory
//括号()通过子shell执行命令分组
[root@lanquark demo]# (pwd;echo $BASH_SUBSHELL)
/root/demo
1
//命令放到后台执行
[root@lanquark demo]# sleep 10 &
[1] 3846
[root@lanquark demo]# jobs
[1]+  Running                 sleep 10 &
[root@lanquark demo]#
//管道符|
[root@lanquark demo]# cat temp | wc -l
25
//标准输出默认输出到显示器。输出重定向,输出内容不在显示器上显示,保存到指定文件中,会清空原有文件
[root@lanquark demo]# ls -l > ls_demo.txt
[root@lanquark demo]# cat ls_demo.txt 
total 24
-rw-r--r--  1 root root    4 Jun  1 07:50 1.txt
-rw-r--r--  1 root root   12 Jun  1 07:51 2.txt
-rw-r--r--  1 root root    0 Jun  2 11:02 3.txt
-rw-r--r--  1 root root   52 Jun  1 07:46 err.txt
-rw-r--r--. 1 root root   16 May 21 00:58 f1.txt
-rw-r--r--  1 root root    0 May 21 19:46 f2.txt
-rw-r--r--  1 root root    0 Jun  2 11:30 ls_demo.txt
-rw-r--r--  1 root root   57 Jun  1 07:48 ls.txt
-rw-r--r--  1 root root 1146 May 25 03:44 temp
-rw-r--r--  1 root root    0 Jun  1 07:28 txt
//输出追加重定
[root@lanquark demo]# echo "I am new" >> ls_demo.txt 
[root@lanquark demo]# cat ls_demo.txt 
total 24
-rw-r--r--  1 root root    4 Jun  1 07:50 1.txt
-rw-r--r--  1 root root   12 Jun  1 07:51 2.txt
-rw-r--r--  1 root root    0 Jun  2 11:02 3.txt
-rw-r--r--  1 root root   52 Jun  1 07:46 err.txt
-rw-r--r--. 1 root root   16 May 21 00:58 f1.txt
-rw-r--r--  1 root root    0 May 21 19:46 f2.txt
-rw-r--r--  1 root root    0 Jun  2 11:30 ls_demo.txt
-rw-r--r--  1 root root   57 Jun  1 07:48 ls.txt
-rw-r--r--  1 root root 1146 May 25 03:44 temp
-rw-r--r--  1 root root    0 Jun  1 07:28 txt
I am new
//标准输入重定向,默认是从键盘。
[root@lanquark demo]# wc -l < /etc/passwd
25
//here文档。
[root@lanquark demo]# cat >>here_document.txt<<EOF
> aaaaaa
> bbbbbb
> cccccc
> EOF
[root@lanquark demo]# cat here_document.txt 
aaaaaa
bbbbbb
cccccc
//星号(*),匹配0个或多个任意字符
[root@lanquark demo]# ls
1.txt  2.txt  3.txt  err.txt  f1.txt  f2.txt  here_document.txt  ls_demo.txt  ls.txt  temp  txt
[root@lanquark demo]# ls  *.txt
1.txt  2.txt  3.txt  err.txt  f1.txt  f2.txt  here_document.txt  ls_demo.txt  ls.txt
//问号(?)匹配任意一个字符
[root@lanquark demo]# ls
1.txt  2.txt  3.txt  err.txt  f1.txt  f2.txt  here_document.txt  ls_demo.txt  ls.txt  temp  txt
[root@lanquark demo]# ls ?.txt
1.txt  2.txt  3.txt
//反引号(\),转义后面的字符
[root@lanquark demo]# echo $myname
hjm
[root@lanquark demo]# echo \$myname
$myname
//单引号所见即所得,双引号会扩展变量和命令
[root@lanquark demo]# myname='hjm'
[root@lanquark demo]# echo '$myname'
$myname
[root@lanquark demo]# echo "$myname"
hjm
//反引号会扩展命令,反引号伴于波浪号下(~)
[root@lanquark demo]# tt=`date +%F`
[root@lanquark demo]# echo $tt
2018-06-02
//[ ]匹配字符类型
[root@lanquark demo]# ls [123].txt
1.txt  2.txt  3.txt
//$引用变量
[root@lanquark demo]# domain='lanquark.com'
[root@lanquark demo]# echo $domain
lanquark.com
//点(.),在当前shell中执行文件中的命令,只在行首
[root@lanquark demo]# cat bbb.sh 
ls -l > lsb.txt
wc -l  lsb.txt

[root@lanquark demo]# . bbb.sh 
18 lsb.txt
[root@lanquark demo]# cat lsb.txt 
total 44
-rw-r--r--  1 root root    4 Jun  1 07:50 1.txt
-rw-r--r--  1 root root   12 Jun  1 07:51 2.txt
-rw-r--r--  1 root root    0 Jun  2 11:02 3.txt
-rw-r--r--  1 root root    0 Jun  2 11:47 a
-rw-r--r--  1 root root  113 Jun  2 11:52 aaa.txt
-rw-r--r--  1 root root    0 Jun  2 11:47 b
-rwxr-xr-x  1 root root   32 Jun  2 12:03 bbb.sh
-rw-r--r--  1 root root   52 Jun  1 07:46 err.txt
-rw-r--r--. 1 root root   16 May 21 00:58 f1.txt
-rw-r--r--  1 root root    0 May 21 19:46 f2.txt
-rw-r--r--  1 root root   21 Jun  2 11:37 here_document.txt
-rw-r--r--  1 root root    0 Jun  2 12:04 lsb.txt
-rw-r--r--  1 root root  506 Jun  2 11:33 ls_demo.txt
-rw-r--r--  1 root root   57 Jun  1 07:48 ls.txt
-rwxr-xr-x  1 root root   25 Jun  2 11:52 shell_demo.txt
-rw-r--r--  1 root root 1146 May 25 03:44 temp
-rw-r--r--  1 root root    0 Jun  1 07:28 txt
//逻辑与&&
[root@lanquark demo]# ls -l err.txt && echo "exist"
-rw-r--r-- 1 root root 52 Jun  1 07:46 err.txt
exist
//逻辑或||
[root@lanquark demo]# ls -ld fd3 || mkdir fd3
ls: cannot access fd3: No such file or directory
[root@lanquark demo]# ls -ld fd3
drwxr-xr-x 2 root root 6 Jun  2 12:09 fd3
//命令替换$(), 作用同反引号,推荐用$()
[root@lanquark demo]# work_place=$(pwd)
[root@lanquark demo]# echo $work_place
/root/demo


二、cut、sort、wc、uniq命令

Cut可以从数据中抽取指定列或字段

cut语法:

cut -c list [file...]

cut -f list [-d delimiteer] [-s] [file...]

list是要抽取的列的列表,file是输入文件的名称

抽取列

//只显示示例文件中的姓名
[root@lanquark demo]# cat sample.txt 
012-34-5678    Ambercrombie, A1    01/01/72    555-1111
123-45-6789    Barton, Barbara     02/02/73    555-2222
234-56-7890    Canby, charles      03/03/74    555-3333
345-67-8901    Danfield, Deam      04/04/75    555-4444
[root@lanquark demo]# cut -c 14-31 sample.txt 
  Ambercrombie, A1
  Barton, Barbara 
  Canby, charles  
  Danfield, Deam 
//显示姓名和电话号码
[root@lanquark demo]# cut -c 14-31,46-55 sample.txt 
  Ambercrombie, A1  555-1111
  Barton, Barbara   555-2222
  Canby, charles    555-3333
  Danfield, Deam    555-4444
//显示每个用户登录了多少次
[root@lanquark]~# who | cut -c 1-8 | sort | uniq -c
      1 hjm     
      3 root    
      1 user1 

抽取数据字段

//抽取一个字段
[root@lanquark]~# cut -f 1 -d ':' /etc/passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
abrt
tss
postfix
chrony
sshd
hjm
user1
user2
user3
//抽取多个字段
[root@lanquark]~# cut -f 1,3-5 -d ':' /etc/passwd
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp
sync:5:0:sync
shutdown:6:0:shutdown
halt:7:0:halt
mail:8:12:mail
operator:11:0:operator
games:12:100:games
ftp:14:50:FTP User
nobody:99:99:Nobody
systemd-network:192:192:systemd Network Management
dbus:81:81:System message bus
polkitd:999:997:User for polkitd
abrt:173:173:
tss:59:59:Account used by the trousers package to sandbox the tcsd daemon
postfix:89:89:
chrony:998:996:
sshd:74:74:Privilege-separated SSH
hjm:5000:5000:HJM
user1:5001:100:
user2:5002:100:
user3:5003:100:
//-f和-d之后的空格可以省略


sort可以排序数据以及查看数据是否排序。

语法: sort [-t 分隔符] [-dfnru] [-o outfile] [infile...]

outfile是存放输出文件的名称,infile是包含输入的文件的名称

-d(directory,字典)只查看字母、数字或空白符。当数据中包含可能妨碍排序过程的字符(例如标点符号时可以用这个选项)

-f(fold,等同)忽略大小写

-n(numeric,数字)选项识别行开头或者字段开头的数字,并按数字进行排序

[root@lanquark]~# cat number.txt 
11
2
1
20
10
[root@lanquark]~# sort number.txt 
1
10
11
2
20
//以第4列按数字排序
[root@lanquark]~/demo# cat num.sort 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@lanquark]~/demo# sort -t ':' -n -k4 num.sort
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

-r(reverse,反向)按反向顺序对数据排序

[root@lanquark]~/demo# cat number.txt 
11
2
1
20
10
[root@lanquark]~/demo# sort -nr number.txt 
20
11
10
2
1

-u 查找相同的行,并将相同的行只留下一行

[root@lanquark]~/demo# cat s_unic.txt 
Barbara
AI
Barbara
Barbara
Dave
[root@lanquark]~/demo# sort -u s_unic.txt 
AI
Barbara
Dave

检查数据是否有序(sort -c)

[root@lanquark]~/demo# cat number.txt 
11
2
1
20
10
[root@lanquark]~/demo# sort -c number.txt 
sort: number.txt:3: disorder: 1

ASCII码排序

sort排序的结果取决于系统中字符的组织方式。

建议采用ASCII字符编码方式排序。

ASCII码排序三个基本原则

1.空格在数字前面

2.数字在大写字母前

3.大写字母在小写字母前面

可以通过设置环境变量LC_COLLATE的值来保证使用ASCII排序

[root@lanquark]~/demo# locale | grep LC_COLLATE
LC_COLLATE="en_US.UTF-8"
[root@lanquark]~/demo# echo 'export LC_COLLATE=C' >> /etc/profile 
[root@lanquark]~/demo# . /etc/profile
[root@lanquark]~/demo# locale | grep LC_COLLATE
LC_COLLATE=C


wc 统计行、单词和字符数量

语法:wc [-clLw] [file...]

不带选项的wc命令统计文件的字符数、单词数和行数

[root@lanquark]~/demo# cat poem 
There was a young man from Nantucket,
Whose girlfriend had told him to
[root@lanquark]~/demo# wc poem 
 2 13 71 poem
//"字符"就是字母、数字、标点符号、空格、制表符或者新行字符
//"单词"就是一串连续的字符,用空格、制表符或新行字符分隔
//"行"就是以新行字符结尾的一串字符

-c 统计字符

[root@lanquark]~/demo# wc -c poem 
71 poem

-l 统计行数

[root@lanquark]~/demo# wc -l poem 
2 poem

[root@lanquark]~/demo# who 
user1    tty1         2018-06-02 12:40
root     pts/0        2018-06-01 00:02 (192.168.1.9)
root     pts/1        2018-06-01 07:25 (192.168.1.9)
root     pts/2        2018-06-02 12:39 (192.168.1.9)
hjm      tty2         2018-06-02 12:40
[root@lanquark]~/demo# who  | wc -l
5

-w 统计单词数

[root@lanquark]~/demo# wc -w poem
13 poem

-L 统计该文件中最长行的长度

[root@lanquark]~/demo# wc -L poem 
37 poem


uniq 一行一行地检查数据,查找连续重复的行

语法:uniq [-cdu] [infile] [outfile]

不带选项的uniq去除重复行的

[root@lanquark]~/demo# cat data 
AI
AI
Barbara
Barbara
Charles
[root@lanquark]~/demo# uniq data
AI
Barbara
Charles
//注意:uniq的输入必须是有序的,所以重复行不连续的

-d 只查看重复行

[root@lanquark]~/demo# uniq -d data
AI
Barbara

-c 统计重复行出现的次数

[root@lanquark]~/demo# uniq -c data 
      2 AI
      2 Barbara
      1 Charles

-u 只查看非重复的行

[root@lanquark]~/demo# uniq -u data 
Charles

<br / >

三、tee、tr、split命令

tee 管道线分流,将程序的输出发送到两个地方,类似于水管的双通头。

tee的作用就是从标准输入读取数据,并向标准输出和一个文件各发送一份数据。

语法: tee [-a] file....

[root@lanquark]~/demo# who | tee status
user1    tty1         2018-06-02 12:40
root     pts/0        2018-06-01 00:02 (192.168.1.9)
root     pts/1        2018-06-01 07:25 (192.168.1.9)
root     pts/2        2018-06-02 12:39 (192.168.1.9)
hjm      tty2         2018-06-02 12:40
[root@lanquark]~/demo# cat status 
user1    tty1         2018-06-02 12:40
root     pts/0        2018-06-01 00:02 (192.168.1.9)
root     pts/1        2018-06-01 07:25 (192.168.1.9)
root     pts/2        2018-06-02 12:39 (192.168.1.9)
hjm      tty2         2018-06-02 12:40

-a (append) 追加到某文件

[root@lanquark]~/demo# netstat -nltup | tee -a status
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1143/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1245/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1143/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1245/master         
udp        0      0 127.0.0.1:323           0.0.0.0:*                           734/chronyd         
udp6       0      0 ::1:323                 :::*                                734/chronyd         
[root@lanquark]~/demo# cat status 
user1    tty1         2018-06-02 12:40
root     pts/0        2018-06-01 00:02 (192.168.1.9)
root     pts/1        2018-06-01 07:25 (192.168.1.9)
root     pts/2        2018-06-02 12:39 (192.168.1.9)
hjm      tty2         2018-06-02 12:40
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1143/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1245/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1143/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1245/master         
udp        0      0 127.0.0.1:323           0.0.0.0:*                           734/chronyd         
udp6       0      0 ::1:323                 :::*                                734/chronyd   


tr 转换字符

tr可以对字符执行三种不同操作。

1.将字符改变成其他字符

2.如果要转换的字符连续出现不止一次,则用一个单独的字符替换,实现去重的效果

3.删除指定字符

常用语法: tr [-cds] [set1 [set2]]

set1和set2是字符组

转换字符

[root@lanquark]~/demo# head -n5 temp > str_sample
[root@lanquark]~/demo# cat str_sample 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@lanquark]~/demo# tr 'root' 'ROOT' < str_sample 
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nOlOgin
daemOn:x:2:2:daemOn:/sbin:/sbin/nOlOgin
adm:x:3:4:adm:/vaR/adm:/sbin/nOlOgin
lp:x:4:7:lp:/vaR/spOOl/lpd:/sbin/nOlOgin
//如需保存替换后的文件,可将转出重定向到某个文件中
[root@lanquark]~/demo# tr 'root' 'ROOT' < str_sample > new
[root@lanquark]~/demo# cat new
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nOlOgin
daemOn:x:2:2:daemOn:/sbin:/sbin/nOlOgin
adm:x:3:4:adm:/vaR/adm:/sbin/nOlOgin
lp:x:4:7:lp:/vaR/spOOl/lpd:/sbin/nOlOgin
//定义字符范围
[root@lanquark]~/demo# tr a-z A-Z < str_sample 
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN
ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN
LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN
//转换不可显示字符
[root@lanquark]~/demo# cat str_sample 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@lanquark]~/demo# tr '\n' '\t'< str_sample
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin    daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin   #

-s 将多个连续字符替换为一个单独的字符。

[root@lanquark]~/demo# cat data1
rootxxx0x0xrootx/rootx/bin/bash
binxxxxxxxbinx/binx/sbin/nologin
daemonxxxxxxxdaemonx/sbinx/sbin/nologin
admxxxxxxxadmx/var/admx/sbin/nologin
lpxxxxxxxlpx/var/spool/lpdx/sbin/nologin
[root@lanquark]~/demo# tr -s x '#' < data1 
//将连续的x替换为一个#
root#0#0#root#/root#/bin/bash
bin#bin#/bin#/sbin/nologin
daemon#daemon#/sbin#/sbin/nologin
adm#adm#/var/adm#/sbin/nologin
lp#lp#/var/spool/lpd#/sbin/nologin

-d 删除指定字符

//删除所有的:号
[root@lanquark]~/demo# cat str_sample 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@lanquark]~/demo# tr -d ':' < str_sample
rootx00root/root/bin/bash
binx11bin/bin/sbin/nologin
daemonx22daemon/sbin/sbin/nologin
admx34adm/var/adm/sbin/nologin
lpx47lp/var/spool/lpd/sbin/nologin
//删除所有的数字
[root@lanquark]~/demo# tr -d 0-9 <str_sample
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
lp:x:::lp:/var/spool/lpd:/sbin/nologin


split 将一个大文件划分成几个小文件

语法 split [-d] [-a num] [-l lines] [file[prefix]]

默认情况下,split创建1000行长的文件

-b 根据文件大小来分割文档,默认单位为byte(字节)

[root@lanquark]~/demo# ls -lh system.log 
-rwxr-x--- 1 root root 6.2M Jun  2 15:57 system.log
[root@lanquark]~/demo# wc -l system.log 
6455 system.log
//以1M为单位分割system.log
//1M=1024b*1024b
[root@lanquark]~/demo# split -b 1048576 system.log 
[root@lanquark]~/demo# ls -lh xa*
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xaa
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xab
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xac
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xad
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xae
-rw-r--r-- 1 root root 1.0M Jun  2 16:03 xaf
-rw-r--r-- 1 root root 108K Jun  2 16:03 xag
//指定分割后产生文件名的开头为000
[root@lanquark]~/demo# split -b 1048576 system.log 000
[root@lanquark]~/demo# ls -l 000*
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000aa
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000ab
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000ac
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000ad
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000ae
-rw-r--r-- 1 root root 1048576 Jun  2 16:08 000af
-rw-r--r-- 1 root root  110592 Jun  2 16:08 000ag

-l以行为单位分割文件

[root@lanquark]~/demo# wc -l system.log 
6455 system.log
//以2000行为单位分割system.log
[root@lanquark]~/demo# split -l 2000 system.log 
[root@lanquark]~/demo# ll -h xa*
-rw-r--r-- 1 root root 461K Jun  2 16:13 xaa
-rw-r--r-- 1 root root 452K Jun  2 16:13 xab
-rw-r--r-- 1 root root 801K Jun  2 16:13 xac
-rw-r--r-- 1 root root 4.5M Jun  2 16:13 xad
//指定分割后产生文件名的开头为000
[root@lanquark]~/demo# ll -h 000*
-rw-r--r-- 1 root root 461K Jun  2 16:14 000aa
-rw-r--r-- 1 root root 452K Jun  2 16:14 000ab
-rw-r--r-- 1 root root 801K Jun  2 16:14 000ac
-rw-r--r-- 1 root root 4.5M Jun  2 16:14 000ad


四、简易审计系统

1.新建记录存放目录

[root@lanquark]~/demo# mkdir -p /usr/local/syslog/records/
[root@lanquark]~/demo# chmod 777 /usr/local/syslog/records 
[root@lanquark]~/demo# chmod +t /usr/local/syslog/records 
[root@lanquark]~/demo# ll -d /usr/local/syslog/records 
drwxrwxrwt 2 root root 6 Jun  2 16:24 /usr/local/syslog/records

2.在/etc/profile里添加如下内容

if [ ! -d /usr/local/syslog/records/${LOGNAME} ]
then
    mkdir -p /usr/local/syslog/records/${LOGNAME}
    chmod 200 /usr/local/syslog/records/${LOGNAME}
fi

export HISTORY_FILE="/usr/local/syslog/records/${LOGNAME}/bash_history"
export PROMPT_COMMAND='{ date "+%F %T ##### $(who am i |awk "{print \$1\" \"\$2\" \"\$5}") #### $(history 1 | { read x cmd; echo "$cmd"; })"; } >>$HISTORY_FILE'

3.测试结果

在一个终端执行的命令可实时在记录文件中查看。

7tRSi.png

7tnTy.png


五、在shell脚本中调用另一个脚本的三种不同方法(fork, exec, source)

1.fork 我们所执行的任何程序,都是父进程 (parent process) 产生的一个子进程 (child process), 子进程在结束后,将返回到父进程去。 此现象在 Linux 中被称为fork。当子进程被产生的时候,将会从父进程那里获得一定的资源分配、及 (更重要的是) 继承父进程的环境。环境变量只能从父进程到子进程单向传递。 换句话说:在子进程中环境如何变更,均不会影响父进程的环境。

shell 脚本就是将你平时在 shell prompt 输入的多行 command line, 依序输入到一个文件文件而已。当我们执行一个 shell script 时,其实是先产生一个 sub-shell, 然后 sub-shell 再去产生命令行的子进程。子shell运行时,父shell处于休眠状态。子shell执行完会唤醒父进程,子shell对环境变量的修改不会影响到你shell。

2.source :就是让shell脚本在当前shell内执行,而不是产生一个子shell。执行完子进程命令后继续执行父进程命令,子进程设置的环境变量会反应到父进程的环境中。

3.exec 与source类似,但是子进程执行完,不会继续执行父进程中的命令。

验证

//1.sh
[root@lanquark ~]# cat 1.sh
#!/bin/bash

A=B
echo "PID for 1.sh before exec/source/fork is:$$"
export A
echo "1.sh:\$A is $A"
case $1 in
    exec)
        echo "using exec..."
    exec ./2.sh;;
    source)
        echo "using source..."
    . ./2.sh;;
    *)
        echo "using fork by default..."
    ./2.sh;;
esac
echo "1.sh:\$A is $A"

//2.sh
[root@lanquark ~]# cat 2.sh 
#!/bin/bash

echo "PID for 2.sh is:$$"
echo "2.sh get \$A=$A from 1.sh"
export A=C
echo "2.sh:\$A is $A"

//在1.sh中以fork方式执行2.sh
[root@lanquark ~]# ./1.sh fork
PID for 1.sh before exec/source/fork is:27181
1.sh:$A is B
using fork by default...
//说明2.sh不是在1.sh同一个shell中执行,进程id不相同
PID for 2.sh is:27182
//子shell继承父shell的环境,所以$A=B
2.sh get $A=B from 1.sh
//子shell中修改A的值
2.sh:$A is C
//子shell环境变量改变不影响父shell
1.sh:$A is B

//在1.sh以exec方式执行2.sh
[root@lanquark ~]# ./1.sh exec
PID for 1.sh before exec/source/fork is:27495
1.sh:$A is B
using exec...
//和父进程的进程ID相同,说明没有产生子shell
PID for 2.sh is:27495
2.sh get $A=B from 1.sh
2.sh:$A is C
//2.sh执行完以后没有回退到1.sh。并且1.sh中的最后一条语句没有执行

//在1.sh以source执行2.sh
[root@lanquark ~]# ./1.sh source
PID for 1.sh before exec/source/fork is:27670
1.sh:$A is B
using source...
//和父进程的进程ID相同,说明没有产生子shell
PID for 2.sh is:27670
2.sh get $A=B from 1.sh
//在子进程中修改了A的值
2.sh:$A is C
//子进程中的修改反映到了父进程中
1.sh:$A is C


参考
https://my.oschina.net/u/3708120/blog/1799467
http://blog.51cto.com/13646023/2105163
http://blog.51cto.com/13646023/2105592
http://ask.apelearn.com/question/7719
http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html
http://ask.apelearn.com/question/5437
http://www.cnblogs.com/lr-ting/archive/2013/02/28/2936792.html
http://alsww.blog.51cto.com/2001924/1113112
http://ask.apelearn.com/question/7720
http://ask.apelearn.com/question/5364
http://ask.apelearn.com/question/5360
http://ask.apelearn.com/question/283
http://ask.apelearn.com/question/909
http://blog.csdn.net/zenghui08/article/details/7938975
https://github.com/wzb56/13_questions_of_shell
http://www.linuxnote.org/prompt_command-environment-variables.html

猜你喜欢

转载自www.cnblogs.com/minn/p/9132051.html