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

三、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.测试结果

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

五、在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

Linux Shell基础(下)的更多相关文章

  1. Linux shell基础知识(上)

    Linux shell基础知识(上) 目录 一.shell介绍 二.命令历史 三.命令补全和别名 四.通配符 五.输入输出重定向 六.管道符和作业控制 七.shell变量 八.环境变量配置文件 九.b ...

  2. linux shell 基础 使用日志与心得

    linux shell 基础 使用日志与心得 1.#!/bin/bash 第一行就出现#!/bin/bash是指此脚本使用/bin/bash来解释执行.其中,#!是一个特殊的表示符,其后,跟着解释此脚 ...

  3. Linux Shell 基础知识(一)

    1. 本文知识结构 2. shell 基础知识 2.1 shell 简单介绍 ​ GNU bash shell 能提供对 Linux 系统的交互式访问,一般来说,使用快捷键 Ctrl + Alt + ...

  4. linux shell基础语法

    1.第一个Shell脚本 打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了. 输入一些代码 ...

  5. Linux shell基础

    shell是核心程序kernel之外的指令解析器,是一个程序,同事是一种命令语言和程序设计语言 --shell是命令解析器,用户输入命令,它去解析. shell类型 ash,bash,ksh,csh, ...

  6. Linux Shell基础 环境变量配置文件

    source命令:使环境变量配置文件强制生效 source 命令会强制执行脚本中的全部命令,而忽略脚本文件的权限.该命令主要用于让重新配置的环境变量配置文件强制生效.source 命令格式如下: [r ...

  7. Linux Shell基础 位置参数变量、预定义变量

    位置参数变量 在 Linux 的命令行中,当一条命令或脚本执行时,后面可以跟多个参数,我们使用位置参数变量来表示这些参数.其中,$0 代表命令行本身,$1 代表第 1 个参数,$2 代表第 2 个参数 ...

  8. Linux Shell基础知识

    一.文件系统和安全 chmod命令 chmod命令有两种模式,一种是符号模式,用ugo执行用户,用rwx执行权限:另一种是绝对模式,用八进制不同位置的不同值来代表不同用户的不同权限. 符号模式 chm ...

  9. Linux shell 基础

    目录 一.shell脚本的基本使用 1.语言规范 2.变量 3.重定向(>,>>) 二.运算符和常用判断 1.比较运算符 2.逻辑运算符 3.常用判断 三.程序结构 1.分支(if语 ...

随机推荐

  1. Gis数据处理

    几何投影和解析投影几何投影是将椭球面上的经纬线网投影到几何平面上,然后将几何面展为平面.几何投影可以分为方位投影.圆柱投影和圆锥投影.这三种投影纬线的形状不同.方位投影纬线的形状是同心圆:圆柱投影纬线 ...

  2. html5 javascript 事件练习3随机键盘

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  3. Linux hostname设置,静态ip设置,hostname与静态ip相互映射

    1,hostname设置 永久设置: centos 7 下,切换到root 用户 vi /etc/hostname 输入要修改的hostname centos 6或者其他linux 系统,可能在/et ...

  4. map的实际操作用并for_each遍历

    #include<iostream> #include<map> #include<algorithm> #include<string> using ...

  5. Docker Weave 介绍 or 工作原理

    Docker Weave Network Weave Network:属于第三方网络项目. Weave在Docker主机之间实现Overlay网络,使用业界标准VXLAN封装,基于UDP传输,也可以加 ...

  6. resmgr:cpu quantum 等待事件 top 1

    早上看昨天现场的报告,发现晚上七八点,resmgr:cpu quantum 等待事件排在i第一位,如下: 该事件是和资源管理相关的,如果启用资源管理计划,就可能遇到这个问题. 所以常规的解决方案是禁用 ...

  7. [c/c++] programming之路(24)、字符串(五)——字符串插入,字符串转整数,删除字符,密码验证,注意事项

    1.将字符串插入到某位置(原字符串“hello yincheng hello cpp hello linux”,查找cpp,找到后在cpp的后面插入字符串“hello c”) 需要用到strstr字符 ...

  8. Virtual DOM 和 diff 算法

    virtual DOM : virtual DOM 用 js 模拟 DOM 结构,用 js 来对比前后变化,提高重绘性能. diff: 比如在 git 中,如果用命令  git diff xxx文件 ...

  9. .NET ActiveMQ类库

    ActiveMQ .NET类库 ActiveMQ是一种开源的,实现了JMS规范的,面向消息(MOM)的中间件,为应用程序提供高效的.可扩展的.稳定的和安全的企业级消息通信. 0. 准备 使用Nuget ...

  10. MYSQL : The user specified as a definer ('root'@'%') does not exist

    The user specified as a definer ('root'@'%') does not exist 此种报错主要是针对访问视图文件引起的(没有权限) 解决方法: 2.进入mysql ...