Shell應(yīng)用示例
根據(jù)時(shí)間創(chuàng)建文件夾
需求:創(chuàng)建10個(gè)目錄,目錄名稱以當(dāng)天時(shí)間開頭,后面拼上目錄編碼
例如:1970-01-01_1
編寫腳本monitor.sh
持續(xù)觀察服務(wù)器每天的運(yùn)行狀態(tài),需要結(jié)合shell腳本程序和計(jì)劃任務(wù),定期跟蹤記錄不同時(shí)段服務(wù)器的cpu負(fù)載,內(nèi)存,交換空間,磁盤使用量等信息
[java] view plain copy#!/bin/bash
#this is the second script!
day_time=`date+“%F %R”`
cpu_test=`uptime`
mem_test=`free -m | grep “mem” | awk ‘{print $2}’`
swap_test=`free -m | grep “mem” | awk ‘{print $4}’`
disk_test=`df -hT`
user_test=`last -n 10`
echo “now is $day_time”
echo “%cpu is $cpu_test”
echo “Numbet of Mem size(MB) is $mem_test”
echo “Number of swap size(MB) is $swap_test”
echo “the disk shiyong qingkuang is $disk_test”
echo “the users login qingkuang is $user_test”
設(shè)置cron任務(wù)
[java] view plain copy*/15 * * * * bash /monitor.sh
55 23 * * * tar cxf /var/log/runrec /var/log/running.today && --remove-files
SHELL編程之常用技巧
/dev和/proc目錄
dev目錄是系統(tǒng)中集中用來(lái)存放設(shè)備文件的目錄。除了設(shè)備文件以外,系統(tǒng)中也有不少特殊的功能通過(guò)設(shè)備的形式表現(xiàn)出來(lái)。設(shè)備文件是一種特殊的文件,它們實(shí)際上是驅(qū)動(dòng)程序的接口。在Linux操作系統(tǒng)中,很多設(shè)備都是通過(guò)設(shè)備文件的方式為進(jìn)程提供了輸入、輸出的調(diào)用標(biāo)準(zhǔn),這也符合UNIX的“一切皆文件”的設(shè)計(jì)原則。所以,對(duì)于設(shè)備文件來(lái)說(shuō),文件名和路徑其實(shí)都不重要,最重要的使其主設(shè)備號(hào)和輔助設(shè)備號(hào),就是用ls -l命令顯示出來(lái)的原本應(yīng)該出現(xiàn)在文件大小位置上的兩個(gè)數(shù)字,比如下面命令顯示的8和0:
[zorro@zorrozou-pc0 bash]$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 5月 12 10:47 /dev/sda12
設(shè)備文件的主設(shè)備號(hào)對(duì)應(yīng)了這種設(shè)備所使用的驅(qū)動(dòng)是哪個(gè),而輔助設(shè)備號(hào)則表示使用同一種驅(qū)動(dòng)的設(shè)備編號(hào)。我們可以使用mknod命令手動(dòng)創(chuàng)建一個(gè)設(shè)備文件:
[zorro@zorrozou-pc0 bash]$ sudo mknod harddisk b 8 0
[zorro@zorrozou-pc0 bash]$ ls -l harddisk
brw-r--r-- 1 root root 8, 0 5月 18 09:49 harddisk123
這樣我們就創(chuàng)建了一個(gè)設(shè)備文件叫harddisk,實(shí)際上它跟/dev/sda是同一個(gè)設(shè)備,因?yàn)樗鼈儗?duì)應(yīng)的設(shè)備驅(qū)動(dòng)和編號(hào)都一樣。所以這個(gè)設(shè)備實(shí)際上是跟sda相同功能的設(shè)備。
系統(tǒng)還給我們提供了幾個(gè)有特殊功能的設(shè)備文件,在bash編程的時(shí)候可能會(huì)經(jīng)常用到:
/dev/null:黑洞文件。可以對(duì)它重定向如何輸出。
/dev/zero:0發(fā)生器。可以產(chǎn)生二進(jìn)制的0,產(chǎn)生多少根使用時(shí)間長(zhǎng)度有關(guān)。我們經(jīng)常用這個(gè)文件來(lái)產(chǎn)生大文件進(jìn)行某些測(cè)試,如:
[zorro@zorrozou-pc0 bash]$ dd if=/dev/zero of=。/bigfile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.3501 s, 3.1 GB/s1234
dd命令也是我們?cè)赽ash編程中可能會(huì)經(jīng)常使用到的命令。
/dev/random:Linux下的random文件是一個(gè)根據(jù)計(jì)算機(jī)背景噪聲而產(chǎn)生隨機(jī)數(shù)的真隨機(jī)數(shù)發(fā)生器。所以,如果容納噪聲數(shù)據(jù)的熵池空了,那么對(duì)文件的讀取會(huì)出現(xiàn)阻塞。
/dev/urandom:是一個(gè)偽隨機(jī)數(shù)發(fā)生器。實(shí)際上在Linux的視線中,urandom產(chǎn)生隨機(jī)數(shù)的方法根random一樣,只是它可以重復(fù)使用熵池中的數(shù)據(jù)。這兩個(gè)文件在不同的類unix系統(tǒng)中可能實(shí)現(xiàn)方法不同,請(qǐng)注意它們的區(qū)別。
/dev/tcp & /dev/udp:這兩個(gè)神奇的目錄為bash編程提供了一種可以進(jìn)行網(wǎng)絡(luò)編程的功能。在bash程序中使用/dev/tcp/ip/port的方式就可以創(chuàng)建一個(gè)scoket作為客戶端去連接服務(wù)端的ip:port。我們用一個(gè)檢查http協(xié)議的80端口是否打開的例子來(lái)說(shuō)明它的使用方法:
[zorro@zorrozou-pc0 bash]$ cat tcp.sh
#!/bin/bash
ipaddr=127.0.0.1
port=80
if ! exec 5《》 /dev/tcp/$ipaddr/$port
then
exit 1
fi
echo -e “GET / HTTP/1.0\n” 》&5
cat 《&51234567891011121314
ipaddr的部分還可以寫一個(gè)主機(jī)名。大家可以用此腳本分別在本機(jī)打開web服務(wù)和不打開的情況下分別執(zhí)行觀察是什么效果。
/proc是另一個(gè)我們經(jīng)常使用的目錄。這個(gè)目錄完全是內(nèi)核虛擬的。內(nèi)核將一些系統(tǒng)信息都放在/proc目錄下一文件和文本的方式顯示出來(lái),如:/proc/cpuinfo、/proc/meminfo。我們可以使用man 5 proc來(lái)查詢這個(gè)目錄下文件的作用。
函數(shù)和遞歸
我們已經(jīng)接觸過(guò)函數(shù)的概念了,在bash編程中,函數(shù)無(wú)非是將一串命令起了個(gè)名字,后續(xù)想要調(diào)用這一串命令就可以直接寫函數(shù)的名字了。在語(yǔ)法上定義一個(gè)函數(shù)的方法是:
name () compound-command [redirection]
function name [()] compound-command [redirection]12
我們可以加function關(guān)鍵字顯式的定義一個(gè)函數(shù),也可以不加。函數(shù)在定義的時(shí)候可以直接在后面加上重定向的處理。這里還需要特殊說(shuō)明的是函數(shù)的參數(shù)處理和局部變量,請(qǐng)看下面腳本:
[zorro@zorrozou-pc0 bash]$ cat function.sh |awk ‘{print “\t”$0}’
#!/bin/bash
aaa=1000
arg_proc () {
echo “Function begin:”
local aaa=2000
echo $1
echo $2
echo $3
echo $*
echo $@
echo $aaa
echo “Function end!”
}
echo “Script bugin:”
echo $1
echo $2
echo $3
echo $*
echo $@
echo $aaa
arg_proc aaa bbb ccc ddd eee fff
echo $1
echo $2
echo $3
echo $*
echo $@
echo $aaa
echo “Script end!”12345678910111213141516171819202122232425262728293031323334
我們帶-x參數(shù)執(zhí)行一下:
+ aaa=1000
+ echo ‘Script bugin:’
Script bugin:
+ echo 111
111
+ echo 222
222
+ echo 333
333
+ echo 111 222 333 444 555
111 222 333 444 555
+ echo 111 222 333 444 555
111 222 333 444 555
+ echo 1000
1000
+ arg_proc aaa bbb ccc ddd eee fff
+ echo ‘Function begin:’
Function begin:
+ local aaa=2000
+ echo aaa
aaa
+ echo bbb
bbb
+ echo ccc
ccc
+ echo aaa bbb ccc ddd eee fff
aaa bbb ccc ddd eee fff
+ echo aaa bbb ccc ddd eee fff
aaa bbb ccc ddd eee fff
+ echo 2000
2000
+ echo ‘Function end!’
Function end!
+ echo 111
111
+ echo 222
222
+ echo 333
333
+ echo 111 222 333 444 555
111 222 333 444 555
+ echo 111 222 333 444 555
111 222 333 444 555
+ echo 1000
1000
+ echo ‘Script end!’
Script end!1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
觀察整個(gè)執(zhí)行過(guò)程可以發(fā)現(xiàn),函數(shù)的參數(shù)適用方法跟腳本一樣,都可以使用n、*、$@這些符號(hào)來(lái)處理。而且函數(shù)參數(shù)跟函數(shù)內(nèi)部使用local定義的局部變量效果一樣,都是只在函數(shù)內(nèi)部能看到。函數(shù)外部看不到函數(shù)里定義的局部變量,當(dāng)函數(shù)內(nèi)部的局部變量和外部的全局變量名字相同時(shí),函數(shù)內(nèi)只能取到局部變量的值。當(dāng)函數(shù)內(nèi)部沒(méi)有定義跟外部同名的局部變量的時(shí)候,函數(shù)內(nèi)部也可以看到全局變量。
bash編程支持遞歸調(diào)用函數(shù),跟其他編程語(yǔ)言不同的地方是,bash還可以遞歸的調(diào)用自身,這在某些編程場(chǎng)景下非常有用。我們先來(lái)看一個(gè)遞歸的簡(jiǎn)單例子:
[zorro@zorrozou-pc0 bash]$ cat recurse.sh
#!/bin/bash
read_dir () {
for i in $1/*
do
if [ -d $i ]
then
read_dir $i
else
echo $i
fi
done
}
read_dir $11234567891011121314151617
這個(gè)腳本可以遍歷一個(gè)目錄下所有子目錄中的非目錄文件。關(guān)于遞歸,還有一個(gè)經(jīng)典的例子,fork炸彈:
。(){ 。|.& };.1
這一堆符號(hào)看上去很令人費(fèi)解,我們來(lái)解釋一下每個(gè)符號(hào)的含義:根據(jù)函數(shù)的定義語(yǔ)法,我們知道。(){}的意思是,定義一個(gè)函數(shù)名子叫“。”。雖然系統(tǒng)中又個(gè)內(nèi)建命令也叫。,就是source命令,但是我們也知道,當(dāng)函數(shù)和內(nèi)建命令名字沖突的時(shí)候,bash首先會(huì)將名字當(dāng)成是函數(shù)來(lái)解釋。在{}包含的函數(shù)體中,使用了一個(gè)管道連接了兩個(gè)點(diǎn),這里的第一個(gè)。就是函數(shù)的遞歸調(diào)用,我們也知道了使用管道的時(shí)候會(huì)打開一個(gè)subshell的子進(jìn)程,所以在這里面就遞歸的打開了子進(jìn)程。{}后面的分號(hào)只表示函數(shù)定義完畢的結(jié)束符,在之后就是調(diào)用函數(shù)名執(zhí)行的。,之后函數(shù)開始遞歸的打開自己,去產(chǎn)生子進(jìn)程,直到系統(tǒng)崩潰為止。
bash并發(fā)編程和flock
在shell編程中,需要使用并發(fā)編程的場(chǎng)景并不多。我們倒是經(jīng)常會(huì)想要某個(gè)腳本不要同時(shí)出現(xiàn)多次同時(shí)執(zhí)行,比如放在crond中的某個(gè)周期任務(wù),如果執(zhí)行時(shí)間較長(zhǎng)以至于下次再調(diào)度的時(shí)間間隔,那么上一個(gè)還沒(méi)執(zhí)行完就可能又打開一個(gè),這時(shí)我們會(huì)希望本次不用執(zhí)行。本質(zhì)上講,無(wú)論是只保證任何時(shí)候系統(tǒng)中只出現(xiàn)一個(gè)進(jìn)程還是多個(gè)進(jìn)程并發(fā),我們需要對(duì)進(jìn)程進(jìn)行類似的控制。因?yàn)椴l(fā)的時(shí)候也會(huì)有可能產(chǎn)生競(jìng)爭(zhēng)條件,導(dǎo)致程序出問(wèn)題。
我們先來(lái)看如何寫一個(gè)并發(fā)的bash程序。在前文講到作業(yè)控制和wait命令使用的時(shí)候,我們就已經(jīng)寫了一個(gè)簡(jiǎn)單的并發(fā)程序了,我們這次讓它變得復(fù)雜一點(diǎn)。我們寫一個(gè)bash腳本,創(chuàng)建一個(gè)計(jì)數(shù)文件,并將里面的值寫為0。然后打開100個(gè)子進(jìn)程,每個(gè)進(jìn)程都去讀取這個(gè)計(jì)數(shù)文件的當(dāng)前值,并加1寫回去。如果程序執(zhí)行正確,最后里面的值應(yīng)該是100,因?yàn)槊總€(gè)子進(jìn)程都會(huì)累加一個(gè)1寫入文件,我們來(lái)試試:
[zorro@zorrozou-pc0 bash]$ cat racing.sh
#!/bin/bash
countfile=/tmp/count
if ! [ -f $countfile ]
then
echo 0 》 $countfile
fi
do_count () {
read count 《 $countfile
echo $((++count)) 》 $countfile
}
for i in `seq 1 100`
do
do_count &
done
wait
cat $countfile
rm $countfile12345678910111213141516171819202122232425
我們?cè)賮?lái)看看這個(gè)程序的執(zhí)行結(jié)果:
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
26
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
13
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
34
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
25
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
45
[zorro@zorrozou-pc0 bash]$ 。/racing.sh
5123456789101112
多次執(zhí)行之后,每次得到的結(jié)果都不一樣,也沒(méi)有一次是正確的結(jié)果。這就是典型的競(jìng)爭(zhēng)條件引起的問(wèn)題。當(dāng)多個(gè)進(jìn)程并發(fā)的時(shí)候,如果使用的共享的資源,就有可能會(huì)造成這樣的問(wèn)題。這里的競(jìng)爭(zhēng)調(diào)教就是:當(dāng)某一個(gè)進(jìn)程讀出文件值為0,并加1,還沒(méi)寫回去的時(shí)候,如果有別的進(jìn)程讀了文件,讀到的還是0。于是多個(gè)進(jìn)程會(huì)寫1,以及其它的數(shù)字。解決共享文件的競(jìng)爭(zhēng)問(wèn)題的辦法是使用文件鎖。每個(gè)子進(jìn)程在讀取文件之前先給文件加鎖,寫入之后解鎖,這樣臨界區(qū)代碼就可以互斥執(zhí)行了:
[zorro@zorrozou-pc0 bash]$ cat flock.sh
#!/bin/bash
countfile=/tmp/count
if ! [ -f $countfile ]
then
echo 0 》 $countfile
fi
do_count () {
exec 3《 $countfile
#對(duì)三號(hào)描述符加互斥鎖
flock -x 3
read -u 3 count
echo $((++count)) 》 $countfile
#解鎖
flock -u 3
#關(guān)閉描述符也會(huì)解鎖
exec 3》&-
}
for i in `seq 1 100`
do
do_count &
done
wait
cat $countfile
rm $countfile
[zorro@zorrozou-pc0 bash]$ 。/flock.sh
10012345678910111213141516171819202122232425262728293031323334
對(duì)臨界區(qū)代碼進(jìn)行加鎖處理之后,程序執(zhí)行結(jié)果正確了。仔細(xì)思考一下程序之后就會(huì)發(fā)現(xiàn),這里所謂的臨界區(qū)代碼由加鎖前的并行,變成了加鎖后的串行。flock的默認(rèn)行為是,如果文件之前沒(méi)被加鎖,則加鎖成功返回,如果已經(jīng)有人持有鎖,則加鎖行為會(huì)阻塞,直到成功加鎖。所以,我們也可以利用互斥鎖的這個(gè)特征,讓bash腳本不會(huì)重復(fù)執(zhí)行。
[zorro@zorrozou-pc0 bash]$ cat repeat.sh
#!/bin/bash
exec 3》 /tmp/.lock
if ! flock -xn 3
then
echo “already running!”
exit 1
fi
echo “running!”
sleep 30
echo “ending”
flock -u 3
exec 3》&-
rm /tmp/.lock
exit 01234567891011121314151617181920
-n參數(shù)可以讓flock命令以非阻塞方式探測(cè)一個(gè)文件是否已經(jīng)被加鎖,所以可以使用互斥鎖的特點(diǎn)保證腳本運(yùn)行的唯一性。腳本退出的時(shí)候鎖會(huì)被釋放,所以這里可以不用顯式的使用flock解鎖。flock除了-u參數(shù)指定文件描述符鎖文件以外,還可以作為執(zhí)行命令的前綴使用。這種方式非常適合直接在crond中方式所要執(zhí)行的腳本重復(fù)執(zhí)行。如:
*/1 * * * * /usr/bin/flock -xn /tmp/script.lock -c ‘/home/bash/script.sh’1
關(guān)于flock的其它參數(shù),可以man flock找到說(shuō)明。
受限bash
以受限模式執(zhí)行bash程序,有時(shí)候是很有必要的。這種模式可以保護(hù)我們的很多系統(tǒng)環(huán)境不受bash程序的誤操作影響。啟動(dòng)受限模式的bash的方法是使用-r參數(shù),或者也可以rbash的進(jìn)程名方式執(zhí)行bash。受限模式的bash和正常bash時(shí)間的差別是:
不能使用cd命令改變當(dāng)前工作目錄。
不能改變SHELL、PATH、ENV和BASH_ENV環(huán)境變量。
不能調(diào)用含有/的命令路徑。
不能使用。執(zhí)行帶有/字符的命令路徑。
不能使用hash命令的-p參數(shù)指定一個(gè)帶斜杠\的參數(shù)。
不能在shell環(huán)境啟動(dòng)的時(shí)候加載函數(shù)的定義。
不能檢查SHELLOPTS變量的內(nèi)容。
不能使用》, 》|, 《》, 》&, &》和 》》重定向操作符。
不能使用exec命令使用一個(gè)新程序替換當(dāng)前執(zhí)行的bash進(jìn)程。
enable內(nèi)建命令不能使用-f、-d參數(shù)。
不可以使用enable命令打開或者關(guān)閉內(nèi)建命令。
command命令不可以使用-p參數(shù)。
不能使用set +r或者set +o restricted命令關(guān)閉受限模式。
測(cè)試一個(gè)簡(jiǎn)單的受限模式:
[zorro@zorrozou-pc0 bash]$ cat restricted.sh
#!/bin/bash
set -r
cd /tmp
[zorro@zorrozou-pc0 bash]$ 。/restricted.sh
。/restricted.sh: line 5: cd: restricted12345678
subshell
我們前面接觸過(guò)subshell的概念,我們之前說(shuō)的是,當(dāng)一個(gè)命令放在()中的時(shí)候,bash會(huì)打開一個(gè)子進(jìn)程去執(zhí)行相關(guān)命令,這個(gè)子進(jìn)程實(shí)際上是另一個(gè)bash環(huán)境,叫做subshell。當(dāng)然包括放在()中執(zhí)行的命令,bash會(huì)在以下情況下打開一個(gè)subshell執(zhí)行命令:
使用&作為命令結(jié)束提交了作業(yè)控制任務(wù)時(shí)。
使用|連接的命令會(huì)在subshell中打開。
使用()封裝的命令。
使用coproc(bash 4.0版本之后支持)作為前綴執(zhí)行的命令。
要執(zhí)行的文件不存在或者文件存在但不具備可執(zhí)行權(quán)限的時(shí)候,這個(gè)執(zhí)行過(guò)程會(huì)打開一個(gè)subshell執(zhí)行。
在subshell中,有些事情需要注意。subshell中的$$取到的仍然是父進(jìn)程bash的pid,如果想要取到subshell的pid,可以使用BASHPID變量:
[zorro@zorrozou-pc0 bash]$ echo $$ ;echo $BASHPID && (echo $$;echo $BASHPID)
5484
5484
5484
2458412345
可以使用BASH_SUBSHELL變量的值來(lái)檢查當(dāng)前環(huán)境是不是在subshell中,這個(gè)值在非subshell中是0;每進(jìn)入一層subshell就加1。
[zorro@zorrozou-pc0 bash]$ echo $BASH_SUBSHELL;(echo $BASH_SUBSHELL;(echo $BASH_SUBSHELL))
0
1
21234
在subshell中做的任何操作都不會(huì)影響父進(jìn)程的bash執(zhí)行環(huán)境。subshell除了PID和trap相關(guān)設(shè)置外,其他的環(huán)境都跟父進(jìn)程是一樣的。subshell的trap設(shè)置跟父進(jìn)程剛啟動(dòng)的時(shí)候還沒(méi)做trap設(shè)置之前一樣。
協(xié)進(jìn)程coprocess
在bash 4.0版本之后,為我們提供了一個(gè)coproc關(guān)鍵字可以支持協(xié)進(jìn)程。協(xié)進(jìn)程提供了一種可以上bash移步執(zhí)行另一個(gè)進(jìn)程的工作模式,實(shí)際上跟作業(yè)控制類似。嚴(yán)格來(lái)說(shuō),bash的協(xié)進(jìn)程就是使用作業(yè)控制作為實(shí)現(xiàn)手段來(lái)做的。它跟作業(yè)控制的區(qū)別僅僅在于,協(xié)進(jìn)程的標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出都在調(diào)用協(xié)進(jìn)程的bash中可以取到文件描述符,而作業(yè)控制進(jìn)程的標(biāo)準(zhǔn)輸入和輸出都是直接指向終端的。我們來(lái)看看使用協(xié)進(jìn)程的語(yǔ)法:
coproc [NAME] command [redirections]1
使用coproc作為前綴,后面加執(zhí)行的命令,可以將命令放到作業(yè)控制里執(zhí)行。并且在bash中可以通過(guò)一些方法查看到協(xié)進(jìn)程的pid和使用它的輸入和輸出。例子:
zorro@zorrozou-pc0 bash]$ cat coproc.sh
#!/bin/bash
#例一:簡(jiǎn)單命令使用
#簡(jiǎn)單命令使用不能通過(guò)NAME指定協(xié)進(jìn)程的名字,此時(shí)進(jìn)程的名字統(tǒng)一為:COPROC。
coproc tail -3 /etc/passwd
echo $COPROC_PID
exec 0《&${COPROC[0]}-
cat
#例二:復(fù)雜命令使用
#此時(shí)可以使用NAME參數(shù)指定協(xié)進(jìn)程名稱,并根據(jù)名稱產(chǎn)生的相關(guān)變量獲得協(xié)進(jìn)程pid和描述符。
coproc _cat { tail -3 /etc/passwd; }
echo $_cat_PID
exec 0《&${_cat[0]}-
cat
#例三:更復(fù)雜的命令以及輸入輸出使用
#協(xié)進(jìn)程的標(biāo)準(zhǔn)輸入描述符為:NAME[1],標(biāo)準(zhǔn)輸出描述符為:NAME[0]。
coproc print_username {
while read string
do
[ “$string” = “END” ] && break
echo $string | awk -F: ‘{print $1}’
done
}
echo “aaa:bbb:ccc” 1》&${print_username[1]}
echo ok
read -u ${print_username[0]} username
echo $username
cat /etc/passwd 》&${print_username[1]}
echo END 》&${print_username[1]}
while read -u ${print_username[0]} username
do
echo $username
done123456789101112131415161718192021222324252627282930313233343536373839404142
執(zhí)行結(jié)果:
[zorro@zorrozou-pc0 bash]$ 。/coproc.sh
31953
jerry:x:1001:1001::/home/jerry:/bin/bash
systemd-coredump:x:994:994:systemd Core Dumper:/:/sbin/nologin
netdata:x:134:134::/var/cache/netdata:/bin/nologin
31955
jerry:x:1001:1001::/home/jerry:/bin/bash
systemd-coredump:x:994:994:systemd Core Dumper:/:/sbin/nologin
netdata:x:134:134::/var/cache/netdata:/bin/nologin
ok
aaa
root
bin
daemon
ftp
http
uuidd
dbus
nobody
systemd-journal-gateway
systemd-timesync
systemd-network
systemd-bus-proxy
systemd-resolve
systemd-journal-remote
systemd-journal-upload
polkitd
avahi
colord
rtkit
gdm
usbmux
git
gnome-initial-setup
zorro
nvidia-persistenced
ntp
jerry
systemd-coredump
netdata1234567891011121314151617181920212223242526272829303132333435363738394041
最后
本文主要介紹了一些bash編程的常用技巧,主要包括的知識(shí)點(diǎn)為:
/dev/和/proc目錄的使用。
函數(shù)和遞歸。
并發(fā)編程和flock。
受限bash。
subshell。
協(xié)進(jìn)程。
至此,我們的bash編程系列就算結(jié)束了。當(dāng)然,shell其實(shí)到現(xiàn)在才剛剛開始。畢竟我們要真正實(shí)現(xiàn)有用的bash程序,還需要積累大量命令的使用。
評(píng)論