這是我學(xué)習(xí)linux以及shell的時(shí)候選擇的一本書(shū),是O'REILLY圖書(shū)系列的《Shell腳本學(xué)習(xí)指南》,看完之后,對(duì)最基本的Linux命令行操作,文本處理,進(jìn)程管理都會(huì)有一個(gè)全方面的認(rèn)識(shí)。
第一章:背景知識(shí)
- POSIX
POSIX,Portable Operating System Interface。
是UNIX系統(tǒng)的一個(gè)設(shè)計(jì)標(biāo)準(zhǔn),很多類UNIX系統(tǒng)也在支持兼容這個(gè)標(biāo)準(zhǔn),如Linux。
遵循這個(gè)標(biāo)準(zhǔn)的好處是軟件可以跨平臺(tái)。所以windows也支持就很容易理解了,那么多優(yōu)秀的開(kāi)源軟件,支持了這個(gè)這些軟件就可能有windows版本,就可以完善豐富windows下的軟件。
第二章:入門(mén)
#!
cat > nursers
#! /bin/bash -
who | wc -l
之后每條命令都會(huì)用bash運(yùn)行
所以,如果是py文件可以在第一行加上#! /bin/python, 這樣就可以使用./來(lái)運(yùn)行它
grep命令
-v 反向選取,輸出選不滿足條件的
printf命令
- 用法與C語(yǔ)言非常接近
tr命令
tr命令可以對(duì)來(lái)自標(biāo)準(zhǔn)輸入的字符進(jìn)行替換、壓縮和刪除
-c或——complerment:取代所有不屬于第一字符集的字符;
-d或——delete:刪除所有屬于第一字符集的字符;
-s或--squeeze-repeats:把連續(xù)重復(fù)的字符以單獨(dú)一個(gè)字符表示;
-t或--truncate-set1:先刪除第一字符集較第二字符集多出的字符
echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -cd '0-9 \n'
1 2 3 4
tr 'A-Z' 'a-z'
重定向與管道
<\ 改變標(biāo)準(zhǔn)輸入
tr命令
translate charactors
tr -d '0-9'
可以將標(biāo)準(zhǔn)輸入中的數(shù)字全都刪除
tr -d '0-9' < mytext.txt
這就改變了標(biāo)準(zhǔn)輸入而是將txt文件中的內(nèi)容進(jìn)行修改
>\ 改變標(biāo)準(zhǔn)輸出
>>\ 輸出到文件時(shí)不覆蓋文件而是附加
|\ 建立管道
program1 | program2
將program1的標(biāo)準(zhǔn)輸出修改為program2的標(biāo)準(zhǔn)輸入
tr -d '\r' < mytext.txt | sort > mytext2.txt
過(guò)程:
- tr的標(biāo)準(zhǔn)輸入改成mytext.txt
- tr的標(biāo)準(zhǔn)輸出變?yōu)閟ort的標(biāo)準(zhǔn)輸入
- sort的標(biāo)準(zhǔn)輸出重定向到mytext2.txt
/dev/null和/dev/tty
/dev/null是一個(gè)垃圾桶,所有輸出到這里的數(shù)據(jù)都會(huì)被扔掉
echo 12321 > /dev/null
/dev/tty將重定向一個(gè)終端,鍵盤(pán)輸入maybe,所以這個(gè)是用來(lái)作為輸入的
read password < /dev/tty
將會(huì)強(qiáng)制從/dev/tty中讀取數(shù)據(jù),一般情況下不寫(xiě)問(wèn)題也不大貌似
stty -echo
可以將輸入不顯示在屏幕上
stty echo
重新顯示
Shell腳本的參數(shù)
$1代表第一個(gè)參數(shù)
$2代表第二個(gè)參數(shù)
cat > finduser
#! /bin/sh
who | grep $1
^D
使用的時(shí)候就可以./finduser lxc
簡(jiǎn)單的執(zhí)行跟蹤
set -x可以設(shè)置是否跟蹤命令,跟蹤命令是指每條命令執(zhí)行時(shí)候在前面價(jià)一個(gè) + 并顯示出來(lái)
一般寫(xiě)在腳本里
.profile .bashrc區(qū)別
.profile是每次登陸時(shí)運(yùn)行
.bashrc是每次運(yùn)行bash時(shí)運(yùn)行
第三章:查找與替換
正則表達(dá)式與BRE,ERE
BRE是基本正則表達(dá)式(Basic Regular Expression)
ERE是擴(kuò)展正則表達(dá)式子(Extended Regular Expression)
BRE是grep的默認(rèn),而程序中一般使用ERE,如python神馬的,+就屬于ERE的meta符號(hào)
grep -E 表示ERE
grep 則表示BRE
一些小筆記
-
.
用來(lái)匹配任意一個(gè)字符 -
+
是之前的字符一個(gè)或多個(gè) ERE -
*
是之前的字符0個(gè)或多個(gè) -
?
是之前的字符有或沒(méi)有 ERE -
[abc]
abc中的一個(gè) -
[a-f0-9]
16進(jìn)制字符 -
(abc)
連續(xù)的abc,代表一個(gè)整體,后面可以以加入*+之類的 ERE -
{a,b}
表示前面的字符出現(xiàn)a,b次,或者可以不寫(xiě)b精確a次,有逗號(hào)表示沒(méi)有上限 - 一些字符集
[:alnum:], [:alpha:]
-
[^]
匹配不在指定字符組內(nèi)的任一字符
sed命令
sed用來(lái)處理文本里的每一行,可以查找,替換,刪除,顯示等等等等,其功能完全包含grep,tr等命令
- 它的最為常用的功能就是s:
sed 's/要匹配的字符/要替換成的字符/g' file
- 其中/代表分界符,可以用其他符號(hào)代替;g代表搜索全文件,不寫(xiě)則找到第一個(gè)就結(jié)束了
舉個(gè)例子:
find /home/tolstoy -type d -print | -type d表示類型為directory
sed 's;/home/tolstoy/;/home/lt/;' |
sed 's/^/mkdir /' | 插入mkdir指令
sh -x -x表示指令追蹤
這里開(kāi)始是我后面補(bǔ)上的筆記:
sed
-n 取消默認(rèn)的輸出
-e 進(jìn)行多項(xiàng)編輯,即進(jìn)行多次sed命令
sed -e '.....' -e '.....'
-f 指定sed腳本的文件名,就是說(shuō)sed命令可以寫(xiě)在一個(gè)腳本里的
p命令,不加-n的話選中的行會(huì)輸出兩遍
sed -n '3,5p' a.txt # 打印第3~5行
sed -n '3,4d' a.txt # 刪除第3~4行
d命令
sed '/My/,/You/d' a.txt #刪除包含"My"的行到包含"You"的行之間的行
sed '/My/,10d' a.txt #刪除包含"My"的行到第十行的內(nèi)容
s命令
sed -n '1,20s/My$/You/gp' datafile
1~20行中,文末的My替換為You并輸出
cut命令
cut 命令從文件的每一行剪切字節(jié)、字符和字段并將這些字節(jié)、字符和字段寫(xiě)至標(biāo)準(zhǔn)輸出。
如果不指定 File 參數(shù),cut 命令將讀取標(biāo)準(zhǔn)輸入。必須指定 -b、-c 或 -f 標(biāo)志之一。
cut
-b :以字節(jié)為單位進(jìn)行分割。這些字節(jié)位置將忽略多字節(jié)字符邊界,除非也指定了 -n 標(biāo)志。
-c :以字符為單位進(jìn)行分割。
-d :自定義分隔符,默認(rèn)為制表符。
-f :與-d一起使用,指定顯示哪個(gè)區(qū)域。
-n :取消分割多字節(jié)字符。僅和 -b 標(biāo)志一起使用。如果字符的最后一個(gè)字節(jié)落在由 -b 標(biāo)志的 List 參數(shù)指示的<br />范圍之內(nèi),該字符將被寫(xiě)出;否則,該字符將被排除。
舉2個(gè)例子:
cut -d : -f 1,5 /etc/passwd 該命令以:分割,取每行的第1,5列
ls -l | cut -c 1-10 該命令取第1~10個(gè)字符,正好是文件的讀寫(xiě)執(zhí)行權(quán)限
join命令
將兩個(gè)文件中,指定欄位內(nèi)容相同的行連接起來(lái)。
awk命令
awk是一種“單命令行程序”
它的使用模式為:
awk 'program' [ file ]
和sed命令很像
其中program的基本格式為 pattern { action }
舉個(gè)例子:
awk -F : '{print $1, $5 }' /etc/passwd 以:作為分隔符,輸出第一字段第五字段
第四章:文本處理工具
sort命令
-r 反轉(zhuǎn) -n 以數(shù)值排序,比如10就要排在2的后面 -k 選擇按第幾個(gè)字段排序,當(dāng)有多個(gè)-k的時(shí)候就優(yōu)先左邊再右邊 -k 1.2,2.3 從第一個(gè)字段的第二個(gè)字符比較到第二個(gè)字段的第三個(gè)字符 -t 選擇字段的分隔符,默認(rèn)以空白分隔 -f 忽略大小寫(xiě) -u 去重
舉幾個(gè)例子:
sort -t: -k4n -k3n /etc/passwd 以:作為分隔符,先按照第四字段數(shù)值排序再按第三字段數(shù)值排序
uniq命令
sort中的-u選項(xiàng)雖然會(huì)刪除重復(fù),但是它知識(shí)按照鍵值進(jìn)行排序而不是按照整行內(nèi)容,因此我們需要uniq命令
uniq -c 在輸出上加上計(jì)數(shù)
舉個(gè)例子:
sort a.txt | uniq
fmt命令
常常用在管道中,用來(lái)重新格式化段落,嘴饞工的功能就是規(guī)定輸出寬度
cat a.txt | fmt -w 50
wc命令
輸出行數(shù),字?jǐn)?shù),字節(jié)數(shù)
cat a.txt | wc
輸出: 18 155 960
-c 字節(jié)數(shù)
-l 行數(shù)
-w 字?jǐn)?shù)
head命令, tail命令
head -n8 顯示前八行
tail -n9 顯示后九行
tail -f -n2 監(jiān)視最后兩行,這時(shí)tail命令永遠(yuǎn)不會(huì)結(jié)束
file命令
file將參數(shù)文件內(nèi)容的前幾個(gè)字節(jié)與樣式數(shù)據(jù)庫(kù)進(jìn)行比對(duì),再輸出一份簡(jiǎn)短報(bào)告
file a.txt
輸出: a.txt: ASCII text
第五章:管道的神奇魔力
umask命令
umask 077 這條命令使得之后創(chuàng)建的文件只有當(dāng)前用戶有讀寫(xiě)權(quán)限
默認(rèn)情況下的umask值是022(可以用umask命令查看),此時(shí)你建立的文件默認(rèn)權(quán)限是644(6-0,6-2,6-2),
建立的目錄的默認(rèn)權(quán)限是755(7-0,7-2,7-2),可以用ls -l驗(yàn)證一下哦 現(xiàn)在應(yīng)該知道umask的用途了吧,
它是為了控制默認(rèn)權(quán)限,不要使默認(rèn)的文件和目錄具有全權(quán)而設(shè)的
文件用6減,目錄用7減
chmod命令
chmod 755 file 數(shù)字命名法
chmod a+x file 文字設(shè)定法
<權(quán)限范圍>+<權(quán)限設(shè)置> 使權(quán)限范圍內(nèi)的目錄或者文件具有指定的權(quán)限
<權(quán)限范圍>-<權(quán)限設(shè)置> 刪除權(quán)限范圍的目錄或者文件的指定權(quán)限
<權(quán)限范圍>=<權(quán)限設(shè)置> 設(shè)置權(quán)限范圍內(nèi)的目錄或者文件的權(quán)限為指定的值
權(quán)限范圍:
u :目錄或者文件的當(dāng)前的用戶
g :目錄或者文件的當(dāng)前的群組
o :除了目錄或者文件的當(dāng)前用戶或群組之外的用戶或者群組
a :所有的用戶及群組,默認(rèn)
權(quán)限代號(hào):
r :讀權(quán)限,用數(shù)字4表示
w :寫(xiě)權(quán)限,用數(shù)字2表示
x :執(zhí)行權(quán)限,用數(shù)字1表示
- :刪除權(quán)限,用數(shù)字0表示
s :特殊權(quán)限
本章內(nèi)容
本章講了很多腳本的實(shí)例,可以把它寫(xiě)到腳本里,一般用法就是
script < infile > outfile
第六章:變量、判斷、重復(fù)動(dòng)作
export, readonly, env, unset命令
LXC=zhu 普通變量,注意不要加空格
export LXC
export LXC=zhu
export -p
export命令是把變量放到環(huán)境里,可供應(yīng)所有執(zhí)行中的程序使用,-p是顯示所有環(huán)境變量
unset LXC unset命令會(huì)刪除變量
readonly LXC=zhu 創(chuàng)建只讀變量
readonly -p
env LXC=dazhu command 這樣會(huì)在command中使用新的LXC變量,但是shell中原來(lái)的LXC不變
$:變量展開(kāi)
$LXC 最普通的
${LXC} 復(fù)雜腳本中最好這樣寫(xiě)
${LXC:-word} 存在則返回LXC,否則返回word
${LXC:=word} 存在則返回LXC,否則返回word且把LXC賦值為word
....類似的還有不少
$1, $2, ... ${10}
位置參數(shù)
有一些特殊變量表示特殊的參數(shù), $
表示把它們顯示出來(lái):
$#, $*, $@.......
這些都是用在腳本里的
shell腳本中的內(nèi)置變量
# 目前進(jìn)程的參數(shù)個(gè)數(shù)
@ 傳遞給當(dāng)前進(jìn)程的命令行參數(shù)
* 當(dāng)前進(jìn)程的命令行參數(shù)
? 前一命令的推出狀態(tài)
$ shell程序的進(jìn)程編號(hào)
0 shell程序的名稱
HOME 根目錄
PPID 父進(jìn)程編號(hào)
算術(shù)運(yùn)算
算數(shù)運(yùn)算與C語(yǔ)言幾乎一模一樣,但是一定要放在$((...))
$((2 + 3))
$((3 && 4)) #1
退出狀態(tài)
每條shell命令都有一個(gè)退出狀態(tài)
0表示進(jìn)程成功,其他數(shù)字都是失敗
可以用$?
來(lái)查看上一條命令的退出狀態(tài)
if-elif-else-fi
shell的if語(yǔ)句比較特殊它接受一個(gè)命令,如果執(zhí)行成功則相當(dāng)于if判斷成功
if grep pattern myfile > /dev/null
then
... grep成功
else
... grep失敗
fi
! && ||
可以被用于腳本中
有一點(diǎn)比較特殊,a && b
, a失敗了就不會(huì)執(zhí)行b,a || b
,a成功了不會(huì)執(zhí)行b
$1, $2, ... ${10}
位置參數(shù)
有一些特殊變量表示特殊的參數(shù), $
表示把它們顯示出來(lái):
$#, $*, $@.......
這些都是用在腳本里的
shell腳本中的內(nèi)置變量
# 目前進(jìn)程的參數(shù)個(gè)數(shù)
@ 傳遞給當(dāng)前進(jìn)程的命令行參數(shù)
* 當(dāng)前進(jìn)程的命令行參數(shù)
? 前一命令的推出狀態(tài)
$ shell程序的進(jìn)程編號(hào)
0 shell程序的名稱
HOME 根目錄
PPID 父進(jìn)程編號(hào)
算術(shù)運(yùn)算
算數(shù)運(yùn)算與C語(yǔ)言幾乎一模一樣,但是一定要放在$((...))
$((2 + 3))
$((3 && 4)) #1
退出狀態(tài)
每條shell命令都有一個(gè)退出狀態(tài)
0表示進(jìn)程成功,其他數(shù)字都是失敗
可以用$?
來(lái)查看上一條命令的退出狀態(tài)
if-elif-else-fi
shell的if語(yǔ)句比較特殊它接受一個(gè)命令,如果執(zhí)行成功則相當(dāng)于if判斷成功
if grep pattern myfile > /dev/null
then
... grep成功
else
... grep失敗
fi
! && ||
可以被用于腳本中
有一點(diǎn)比較特殊,a && b
, a失敗了就不會(huì)執(zhí)行b,a || b
,a成功了不會(huì)執(zhí)行b
test命令
test [ expression ]
[ [ expression ] ]
這兩種寫(xiě)法都是可以的
test string 返回string是不是null
test -b file file是塊設(shè)備文件
test -d file file是目錄
...
test s1 = s2 字符串s1與s2相同
test n1 -lt n2 n1小于n2
...
用來(lái)返回真?zhèn)危梢杂迷谀_本的if語(yǔ)句中
一般腳本里會(huì)這樣寫(xiě)
if [ "X$1" = "X-f" ] X防止字符串是空的
then
...
case語(yǔ)句
語(yǔ)法有點(diǎn)特殊,用到再查吧
后面有用到
for循環(huán)
第一種:
for i in atl*.xml
do
echo $i
mv $i $i.old
sed '.....' < $i.old >$i
done
第二種
for i # 循環(huán)命令行參數(shù)
do
case $i in
-f) ...
;;
...
esac
done
while和until循環(huán)
while(until) condition
do
statements
done
while是condition成功返回就繼續(xù)執(zhí)行,until是反之
shell也有break和continue
shift命令
shift讓所有參數(shù)順移
原來(lái)的$1沒(méi)了, 原來(lái)的$2變成$1, ...
配合
while [ $# -gt 0 ]
do
shift
done
可以對(duì)一個(gè)個(gè)參數(shù)進(jìn)行處理!
getops命令
簡(jiǎn)化腳本的參數(shù)處理
#!/bin/bash
while getopts "a:bc" arg #選項(xiàng)后面的冒號(hào)表示該選項(xiàng)需要參數(shù),即必選
do
case $arg in
a)
echo "a's arg:$OPTARG" #參數(shù)存在$OPTARG中
;;
b)
echo "b"
;;
c)
echo "c"
;;
?) #當(dāng)有不認(rèn)識(shí)的選項(xiàng)的時(shí)候arg為?
echo "unkonw argument"
exit 1
;;
esac
done
函數(shù)
wait_for_user () {
until who | grep "$1" > /dev/null
do
sleep ${2:-30}
done
}
用法
wait_for_user phil
wait_for_user phil 60
- 在函數(shù)中,
$1, $2
變成了傳遞給函數(shù)的參數(shù)而不是腳本的參數(shù),函數(shù)之行完畢就恢復(fù) - 函數(shù)可以使用return來(lái)返回執(zhí)行狀態(tài),不寫(xiě)的話就默認(rèn)為
return $?
- 函數(shù)里并沒(méi)有局部變量,和全局都是共享的
第七章:輸入輸出、文件與命令執(zhí)行
read命令
read lxc
read還可以一次讀入多個(gè)變量,分割符默認(rèn)空格,為$IFS的值
重定向
腳本正文內(nèi)提供輸入數(shù)據(jù)
<< EOF
cat << EOF
> one
> two
> EOF
one
two
文件描述符
0,1,2: 標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤輸出
make > results.txt 2>&1
上面這個(gè)命令順序很重要,反了就不對(duì)
exec命令可以改變shell本身I/O設(shè)置
exec 2> /tmp/file
exec 3< /some/file
read lxc <&3
printf
printf "%.2f %s\n" 123.4567 abc
123.46 abc
~波浪號(hào)展開(kāi)
vi ~/.profile #當(dāng)前用戶根目錄
vi ~phil/.profile #phil用戶的根目錄
read user
vi ~$user/.profile
通配符
? 任意單個(gè)字符
* 任何字符串
[set] 任何在set內(nèi)的字符
[!set] 任何不在set的字符
echo 加帶通配符的內(nèi)容,用來(lái)顯示當(dāng)前目錄下符合條件的文件名
echo .* #顯示隱藏文件
$() 命令替換
$()
里面可以加上命令,并把輸出放入其他命令中
舉個(gè)例子,實(shí)現(xiàn)head -10 file
count=$(echo $1 | sed 's/^-//')
shift
sed ${count}q "$@"
算術(shù)運(yùn)算
i=1
while [ "$i" -le 5 ]
do
echo i is $i
i=$((i + 1))
done
轉(zhuǎn)義
echo \* 單個(gè)反斜杠可以轉(zhuǎn)義
*
echo ' $ \' 單引號(hào)內(nèi)的全部看成原來(lái)的意思
$ \
# 雙引號(hào)會(huì)正確處理所有meta字符
# 所以說(shuō)單引號(hào)和雙引號(hào)功能是完全不同的
eval語(yǔ)句
eval的作用是取出參數(shù),并再執(zhí)行它們一次
舉個(gè)例子稍微體會(huì)一下
list page="ls | more"
$listpage #會(huì)報(bào)錯(cuò),找不到|
eval $listpage #會(huì)正常執(zhí)行的
subShell與代碼塊
這些是一起執(zhí)行的代碼,區(qū)別是放在()
中的是開(kāi)新進(jìn)程,放在{}
中的不開(kāi)新進(jìn)程
比如在新進(jìn)程中使用cd就不會(huì)改變當(dāng)前的目錄
內(nèi)建命令
shell中命令的查找順序?yàn)椋?/p>
- 特殊內(nèi)建命令
- 腳本里的函數(shù)
- 一般內(nèi)建命令
-
$PATH
中的東西
alias命令
alias lxc="ls -a"
unalias lxc
source 與 ./
執(zhí)行的區(qū)別
source是讀取文件并執(zhí)行其中的命令,不需要執(zhí)行權(quán)限!
.是source的別名
./中的.是當(dāng)前目錄的意思,是需要執(zhí)行權(quán)限的!
set命令
功能很多
set -x 命令跟蹤
set -o xtrace 同上
set +o xtrace 關(guān)閉
set有一種格式是set -o .... 打開(kāi)某個(gè)功能,set +o ...關(guān)閉某個(gè)功能
第八章:產(chǎn)生腳本
本章介紹了兩個(gè)腳本
一個(gè)是pathfind,一個(gè)是build-all
awk程序
工作模式:
awk 'pattern {action}' file
awk -f programfile inputfiles
一些例子:
emp.data:
Beth 4.00 0
Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
1.基本用法:
awk '$3 >0 { print $1, $2 * $3 }' emp.data
2.pattern和action都可以省略
省略pattern就匹配每一行
省略action就print匹配的行
3.內(nèi)建變量
$0:整行, $1~$n:第某個(gè)字段
NF:字段個(gè)數(shù), $NF最后一個(gè)字段
NR:行號(hào)
4.可以使用printf
{ printf("%-8s $%6.2f\n", $1, $2 * $3) }
第一個(gè)規(guī)格 %-8s 將一個(gè)姓名以字符串形式在8個(gè)字符寬度的字段中左對(duì)齊輸出。第二個(gè)規(guī)格 %6.2f 將薪酬以數(shù)字的形式,保留小數(shù)點(diǎn)后兩位,在6個(gè)字符寬度的字段中輸出。
5.多樣的pattern
!($2 < 4 && $1 == "Susie")
6.BEGIN和END
BEGIN用于第1行前
END用于最后一行后面
這個(gè)可以用來(lái)使得輸出更明確
7.使用變量
{ pay = pay + $2 * $3 }
END { print NR, "employees"
print "total pay is", pay
print "average pay is", pay/NR
}
8.內(nèi)置函數(shù)
length($1) 統(tǒng)計(jì)$1字符個(gè)數(shù)
9.action里面還支持一些for,if,while語(yǔ)句
10.還支持?jǐn)?shù)組
第十章:文件處理
ls命令
一般用到-a -l
ls -al
drwx------+ 4 luphil staff 136 12 7 13:02 Desktop
第二欄代表link數(shù)量
倒數(shù)二三四是時(shí)間,日,月 (近六個(gè)月中的最后修改時(shí)間)
stat命令
stat可以列出文件的meta信息
使用touch命令修改時(shí)間戳
touch a
# 若a存在則更新a的最后修改時(shí)間
touch -t 199212210800.00 mybirthday
# 創(chuàng)造特定時(shí)間戳
臨時(shí)文件
可以放到/tmp中去
為了防止臨時(shí)文件和其他用戶的文件重復(fù)了,可以使用
touch abc.$$
這樣子創(chuàng)建的文件名就帶上了進(jìn)程號(hào)
mktemp 創(chuàng)建臨時(shí)文件
mktemp lxc.XXXXXXXX 在當(dāng)前目錄創(chuàng)建臨時(shí)文件,隨機(jī)值會(huì)替換XXXX
cat /dev/random | od -x | tr -d ' ' | head -1
/dev/random和/dev/urandom可以源源不斷產(chǎn)生隨機(jī)值
尋找文件
locate
對(duì)文件名建立數(shù)據(jù)庫(kù),快速查找文件which
找PATH下的文件type
type gcc
gcc is /usr/locl/bin/gcc
- find
強(qiáng)大
find命令
find 要尋找的目錄 選項(xiàng)
-atime n n天前訪問(wèn)的文件
-ctime
-follow
-group g 選定組
-links n 擁有n個(gè)鏈接
-ls 類似ll的樣子輸出
-mtime n n天前改過(guò)
-perm 選定權(quán)限
-name 'pattern'
-size n +n -n 大小為n,大于n,小于n,+-適用于其他選項(xiàng)
-type t d為目錄,f為文件,l為鏈接
-user u 選定用戶
xargs命令
之所以能用到這個(gè)命令,關(guān)鍵是由于很多命令不支持|管道來(lái)傳遞參數(shù),而日常工作中有有這個(gè)必要,所以就有了xargs命令,例如:
find /sbin -perm +700 |ls -l 這個(gè)命令是錯(cuò)誤的
find /sbin -perm +700 |xargs ls -l 這樣才是正確的
df命令
df (disk free) 提供單行摘要,一行顯示一個(gè)加載的文件系統(tǒng)的已使用和可用空間,默認(rèn)是整個(gè)系統(tǒng)
df -k 按照KB來(lái)顯示
df -h 按照用戶最易讀懂的方式來(lái)顯示
df -i 按照inode來(lái)顯示
inode:文件數(shù)據(jù)都儲(chǔ)存在"塊"中,那么很顯然,我們還必須找到一個(gè)地方儲(chǔ)存文件的元信息,比如文件的創(chuàng)建者、文件的創(chuàng)建日期、文件的大小等等。這種儲(chǔ)存文件元信息的區(qū)域就叫做inode,中文譯名為"索引節(jié)點(diǎn)"。
每個(gè)inode節(jié)點(diǎn)的大小,一般是128字節(jié)或256字節(jié)。inode節(jié)點(diǎn)的總數(shù),在格式化時(shí)就給定,一般是每1KB或每2KB就設(shè)置一個(gè)inode。假定在一塊1GB的硬盤(pán)中,每個(gè)inode節(jié)點(diǎn)的大小為128字節(jié),每1KB就設(shè)置一個(gè)inode,那么inode table的大小就會(huì)達(dá)到128MB,占整塊硬盤(pán)的12.8%。
stat命令查看inode信息
du命令
du用來(lái)提供一個(gè)目錄的已經(jīng)使用空間,默認(rèn)是遞歸當(dāng)前目錄
du -k 按kb顯示
du -s 不遞歸,僅顯示當(dāng)前目錄
du -h 以友好形式輸出,就是會(huì)自動(dòng)換算成GB,MB等
du -h -s /var/log /var/tmp
200M /var/log
8.0k /var/tmp
cmp命令和diff命令
cmp命令告訴你第一個(gè)不同的位置并且返回一個(gè)失敗離開(kāi)碼
diff則會(huì)詳細(xì)告訴你不同點(diǎn)在哪里
md5sum命令
md5sum file1 file2 file3 ...
可以列出各個(gè)文件的md5值,注意inode和文件是分開(kāi)的,所以只要內(nèi)容一樣就可以了
擴(kuò)展實(shí)例:合并用戶數(shù)據(jù)庫(kù)
合并兩個(gè)server的/etc/passwd
tee命令
在使用管道時(shí)往標(biāo)準(zhǔn)輸出也顯示
echo hello | tee file
拼寫(xiě)檢查
spell,ispell等等,以及awk寫(xiě)的
第十三章:進(jìn)程
ps命令
ps -l 長(zhǎng)輸出
ps -e 顯示所有進(jìn)程,否則只是當(dāng)前進(jìn)程
另外top命令動(dòng)態(tài)顯示
kill命令
kill其實(shí)是傳送信號(hào)(signal)給指定的執(zhí)行中的進(jìn)程。
kill的用法應(yīng)該是
kill -signal pid
舉個(gè)例子:
kill -STOP 17787
sleep 3600 && kill -CONT 17787 &
把17787暫停,然后一小時(shí)后繼續(xù)啟動(dòng),&表示這條命令放到后臺(tái)運(yùn)行
kill 的默認(rèn)信號(hào)是 kill -TERM
trap 命令
trap是一個(gè)shell內(nèi)建命令,它用來(lái)在腳本中指定信號(hào)如何處理。
比如,按Ctrl+C會(huì)使腳本終止執(zhí)行,實(shí)際上系統(tǒng)發(fā)送了SIGINT信號(hào)給腳本進(jìn)程,
SIGINT信號(hào)的默認(rèn)處理方式就是退出程序。如果要在Ctrl+C不退出程序,
那么就得使用trap命令來(lái)指定一下SIGINT的處理方式了。
trap命令不僅僅處理Linux信號(hào),還能對(duì)腳本退出(EXIT)、
調(diào)試(DEBUG)、錯(cuò)誤(ERR)、返回(RETURN)等情況指定處理方式。
舉個(gè)例子
在進(jìn)程號(hào)為24286的進(jìn)程中:
trap 'echo Ignoring HUP' HUP
$ kill -HUP 24286
$ Ignoring HUP
兩個(gè)信號(hào)不能捕捉,一個(gè)是KILL,一個(gè)是STOP
進(jìn)程系統(tǒng)調(diào)用的追蹤
系統(tǒng)調(diào)用(英語(yǔ):system call),又稱為系統(tǒng)呼叫,
指運(yùn)行在使用者空間的程序向操作系統(tǒng)內(nèi)核請(qǐng)求需要更高權(quán)限運(yùn)行的服務(wù)。
系統(tǒng)調(diào)用提供用戶程序與操作系統(tǒng)之間的接口。
大多數(shù)系統(tǒng)交互式操作需求在內(nèi)核態(tài)執(zhí)行。如設(shè)備IO操作或者進(jìn)程間通信。
比如fork,exit,getpid等等都是系統(tǒng)調(diào)用
有一些命令可以跟蹤某個(gè)程序的系統(tǒng)調(diào)用,比如trace等等
延遲的進(jìn)程調(diào)度
sleep
at:指定時(shí)間
batch:加入批處理隊(duì)列
crontab:重復(fù)執(zhí)行某些工作
Shell可移植性議題與擴(kuò)展
本章比較了ksh和bash的異同點(diǎn)
set命令
set命令作用主要是顯示系統(tǒng)中已經(jīng)存在的shell變量,
以及設(shè)置shell變量的新變量值。
set +o 列出所有已經(jīng)設(shè)置的shell變量,這里的變量感覺(jué)更像是一些配置
bash另外有shopt命令來(lái)配置shell變量
在ksh中執(zhí)行set顯示出來(lái)完全不同,所以是當(dāng)前shell的配置,個(gè)人理解
第十五章:安全的shell腳本:起點(diǎn)
一個(gè)有趣的木馬,假設(shè)PATH第一個(gè)為~lxc/bin,當(dāng)lxc以sudo grep運(yùn)行時(shí),
就執(zhí)行了nusty stuff
/bin/grep "$@"
case $(whoami) in
root) nasty stuff
rm ~lxc/bin/grep
;;
esac