第1章 小試牛刀
$ 是普通用戶,# 表示管理員用戶 root。
shebang:
#!。sharp / hash / mesh 稱呼 #,bang 稱呼 !。后接解釋器命令路徑。兩種運行腳本方式:作為命令行參數(shù)(無需 shebang),或授予腳本執(zhí)行權(quán)限。
echo后無引號或使用單引號,無須轉(zhuǎn)義字符\;雙引號中使用轉(zhuǎn)義字符須使用-e;無引號時后面的文本中不能有;;變量替換在單引號中無效。printf不像echo會自動添加換行符。取消echo自動添加換行符須使用-n。%[-][n]s,-為左對齊,n為字符串內(nèi)的字符數(shù),如n小于命令后對應(yīng)的字符串長度,則n被忽略。打印紅色文本,
echo -e "\e[1;31m This is red text. \e[0m"。\e[1;31m將顏色設(shè)為紅色,\e[0m將顏色重置回。常用背景顏色代碼:重置=0,黑色=30,紅色=31,綠色=32,黃色=33,藍色=34,洋紅=35,青色=36,白色=37。常用背景顏色代碼:重置=0,黑色=40,紅色=41,綠色=42,黃色=43,藍色=44,洋紅=45,青色=46,白色=47。Bash 中每一個變量的值都是字符串。
進程的環(huán)境變量可用
cat /proc/$PID/environ得到,PID/environ | tr '\0' '\n'```每行顯示一個,更清楚。
var=value是賦值操作,var = value是相等操作。獲取字符串長度
${#var}。當前使用 shell:
echo $SHELL或echo $0。root 用戶的 $UID 是0。
PS1 是終端提示字符串。
自定義添加路徑函數(shù):
prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }。
使用:prepend PATH /opt/myapp/bin。let result=no1+no2,result=$[ no1 + no2 ],result=$(( no1 + no2 )),三者等價。等號后的變量名前加$亦可。高精度計算:
echo "scale=16; $no1 ^ $no2" | bc。此處 no2 必須為整數(shù)。重定向 stdin:
0>(>)。重定向 stdout:1>(>)。重定向 stderr:2>(>)。tee屏顯加保存,僅保存 stdout。有-a為追加內(nèi)容,沒有為覆蓋。將 out 的內(nèi)容寫入 log.txt:
out 文件內(nèi)容:
#!/bin/bash
cat << EOF > log.txt
hi
hello
EOF
運行 . out,log.txt 的內(nèi)容為:
hi
hello
定義數(shù)組
array_var=(1 2 3 4 5)。打印特定元素echo ${array_var[$index]}。以清單形式打印所有元素echo ${array_var[*]},或echo ${array_var[@]}。打印數(shù)組長度echo ${#array_var[*]}。列出數(shù)組索引echo ${!array_var[*]}。定義關(guān)聯(lián)數(shù)組(Bash 4.0 以上版本)
declare -A ass_array。賦值ass_array=([index1]=val1 [index2=val2]),或ass_array[index1]=val1; ass_array[index2]=val2。設(shè)置命令別名:
alias new_command='command sequence'。不使用別名:
\command。尤其對于特權(quán)命令,可避免攻擊者使用別名盜取信息。獲取終端行數(shù)和列數(shù):
tput culs,tput lines。
打印出當前終端名:tput longname。
將光標移到坐標(10,10)處:tput cup 10 10。
設(shè)置終端背景色:tput setb n。n 可在0至7之間取值。
設(shè)置終端前景色:tput setf n。
設(shè)置粗體:tput bold。
設(shè)置下劃線:tput smul。
刪除從當前光標位置以后的所有內(nèi)容:tput ed。禁止將輸出發(fā)送到終端:
#!/bin/bash
echo -e "Enter password: "
stty -echo
read password
stty echo
echo
echo Password read.
紀元時或 Unix 時間:自世界標準時間(UTC)1970年1月1日0時0分0秒起所流逝的秒數(shù)。
當前紀元時:
date +%s。
日期串轉(zhuǎn)換成紀元時:date --date "Thu Nov 18 08:07:21 IST 2010" +%s。--date用于提供日期串。
轉(zhuǎn)換為星期幾:date --date "Jan 20 2001" +%A。
打印日期:date "+%s/S/M/I/H/d/b/B/m/y/Y/a/A/D"。
設(shè)置日期:date -s "格式化的日期字符串"。倒計時:
#!/bin/bash
echo -n count:
tput sc
count=11
while true
do
if [ $count -gt 0 ]
then
let count--
sleep 1
tput rc
tput ed
echo -n $count
else exit 0
fi
done
- 啟用調(diào)試:
bash -x script.sh。
部分調(diào)試:
#!/bin/bash
for i in {1..6}
do
set -x
echo $i
set +x
done
echo "Script executed."
執(zhí)行時顯示:-x。讀取時顯示:-v。
#!/bin/bash改為#!/bin/bash -xv,則直接運行即可。
自定義調(diào)試信息:
#!/bin/bash
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@ || :
}
for i in {1..10}
do
DEBUG echo $i
done
此處echo $i即為調(diào)試信息。
- 遞歸函數(shù):
Fork Bomb
:(){ :|:& }; :
即
:()
{
: | : &
}
:
: 為函數(shù)名。可通過ulimit -u 128(暫時)或修改配置文件 /etc/security/limits.conf 來限制可生成的最大進程數(shù)來避開。
導(dǎo)出函數(shù):
export -f fname。退出狀態(tài):
$?。成功則為0,否則為非0。如果最后設(shè)置了exit n,則總返回 n。子 shell 法:
cmd_output=$(ls | cat -n)。
反引用或反標記法:cmd_output=`ls | cat -n`。
保留空格和換行符:echo "$cmd_output"。使用子 shell
():
pwd
(cd /bin; ls)
pwd
子 shell 中的命令對當前 shell 沒有影響。
讀取 n 個字符并存入變量:
read -n number_of_chars variable_name。
用無回顯的方式讀取密碼:read -s var。
顯示提示信息:read -p "xxx" var。
在特定時限內(nèi)讀取輸入:read -t timeout var。
用特定的定界符作為輸入行的結(jié)束:read -d ":" var。含延時重復(fù)函數(shù):
repeat()
{
while true
do
$@ && return
sleep 30
done
}
更快的做法:repeat() { while :; do $@ && return; sleep 30; done}。
:是內(nèi)建命令,總返回0。
- 更改定界符:
data="name,sex,rollno,location"
oldIFS=$IFS
IFS=,
for item in $data
do
echo Item: $item
done
IFS=$oldIFS
#!/bin/bash
line="root:x:0:0:root:/root:/bin/bash"
oldIFS=$IFS
IFS=:
count=0
for item in $line
do
[ $count -eq 0 ] && user=$item
[ $count -eq 6 ] && shell=$item
let count++
done
IFS=$oldIFS
echo $user\'s shell is $shell
條件為真則執(zhí)行 action:
[ condition ] && action。
條件為假則執(zhí)行 action:[ condition ] || action。使用字符串比較時,最好用雙中括號,因為單中括號有時回產(chǎn)生錯誤。用
test可以避免使用過多的括號。
第2章 命令之樂
壓縮相鄰空白行:
cat -s file。
將制表符顯示為^I:cat -T file,對排除縮進錯誤非常有用。
顯示行號:cat -n file,空白行不標號則用-b。錄制終端會話:
script -t 2> timing.log -a output.session,之后進行命令行操作,以exit結(jié)束錄制。
播放:scriptreplay timing.log output.session。find .類似ls。find . -print0將以 NULL 取代空格作為分隔符,在文件名中含空格時有用。
忽略字母大小寫:find path -iname。
匹配多個條件中的一個:\( -name "*.txt" -o -name "*.pdf" \)。
同時搜索文件和文件夾:-path。
正則表達式搜索:-regex或忽略大小寫-iregex。
否定參數(shù):! -name。
限制目錄深度:最大深度-maxdepth,開始的最小深度-mindepth。這個選項應(yīng)該放在最前面,以避免多余的搜索。
按類型搜索:-type f/l/d/c/b/s/p。
按時間搜索:最近7天內(nèi)訪問過-atime -7,恰好7天前修改過-mtime 7,超過7天前變化過-ctime +7。如計量時間為分鐘,則用-amin/-mmin/-cmin。比參考文件更新-newer file_to_be_compared。
按大小搜索:-size nb/c/w/k/M/G。
刪除找到的文件:在最后加-delete。
按特定權(quán)限搜索:-perm。
按所有權(quán)搜索:-user。
對搜索到的文件執(zhí)行命令:-exec command/batch_file {} \;。{}將替換為搜索到的文件名。\;表示命令結(jié)束。{} +可減少命令運行次數(shù)。
跳過特定的目錄:find . \( -name ".git" -prune \) -o \( -type f -print \)。多行輸入轉(zhuǎn)單行輸出:
cat example.txt | xargs。
單行輸入轉(zhuǎn)多行輸出:cat example.txt | xargs -n 3。此處每行3個參數(shù)。
指定定界符:xargs -d。默認為空格。
固定格式選項:cat args.txt | xargs -I {} command/batch_file -p {} -l。args.txt中有幾個參數(shù),命令就會執(zhí)行幾次。
統(tǒng)計目錄中所有 C 程序文件的行數(shù):find . -type f -name "*.c" -print0 | xargs -0 wc -l。必須使用-print0和-0,因文件名中可能包含空格。
對同一參數(shù)執(zhí)行多條命令:cat files.txt | ( while read arg; do cat $arg; done )。ROT13 加密:
echo "xxxxxx" | tr 'a-zA-Z' 'n-za-mN-ZA-M'。
刪除字符:cat "Hello 123 World 456" | tr -d '0-9'。
刪除補集之外的所有字符:echo "a 1 b 2 c 3" | tr -d -c '0-9 \n'。
壓縮重復(fù)字符:tr -s char。
列數(shù)字求和:cat sum.txt | echo $( tr '\n' '+' ) 0 | bc -l。
字符類替換:tr '[:lower:]' '[:upper:]'。其余字符類包括alnum/alpha/cntrl/digit/graph/print/punct/space/xdigit。輸出校驗和到文件:
md5sum file1 file2 ... > file_sum.md5。
校驗:md5sum -c *.md5。須與被校驗文件在同一目錄下。
sha1sum用法同md5sum。二者均為單向散列算法,無法逆推出原始數(shù)據(jù),是存儲密碼的理想方案。但是由于計算能力攀升使其容易破解,推薦使用bcrypt或sha512sum。
輸出整個目錄的校驗和:md5deep -rl directory_path > directory.md5,或find directory_path -type f -print0 | xargs -0 md5sum >> directory.md5。crypt加密文件:crypt < input_file > encrypted_file,或直接提供口令crypt PASSPHRASE < input_file > encrypted_file。
解密:crypt PASSPHRASE -d < encrypted_file > output_file。gpg加密文件:gpg -c filename,輸入口令后生成filename.gpg。
解密:gpg filename.gpg。base64加密:base64 file > output。
解密:base64 -d output > file。生成 shadow 密碼字符串:
openssl passwd -1 -salt random_string password。-1指使用 MD5 基于 BSD 的密鑰算法。檢查是否已經(jīng)排序:
sort -C。
按第二列的第二個字符至第四個字符排序:sort -k 2.2,2.4。
后接xargs對行做操作時用:sort -z file | xargs -0 command。
重復(fù)的行僅輸出一次:sort file | uniq。僅輸出不重復(fù)的行:uniq -u。統(tǒng)計出現(xiàn)次數(shù)uniq -c。顯示重復(fù)的行uniq -d。創(chuàng)建臨時文件:
filename=`mktemp`。
創(chuàng)建臨時目錄:dirname=`mktemp -d`。
生成臨時文件名:tmpfile=`mktemp -u`。
按模板創(chuàng)建:mktemp tmp_model.xxx。至少3個 xxx。按大小或行數(shù)等分割文件:
split。
按內(nèi)容分割文件:csplit file /SpecificWord/ -n 2 -s {*} -f filename -b "%02d.suffix"。-s為靜默模式。{*}表示重復(fù)進行直到文件結(jié)束;若*為數(shù)字,表示進行分割的次數(shù)。-n指定分割后-f指定的文件名filename后的數(shù)字個數(shù)。-b指定filename后的數(shù)字格式及后綴。提取文件名和擴展名:
file="sample.jpg"
name=${file%.*}
extension=${file#*.}
%從右向左找最短匹配并刪除,%%找最長匹配并刪除。#和##則從左向右找。
- 批量重命名:
#!/bin/bash
# 將當前目錄下的png和jpg文件重命名
count=1
for img in `find . -iname '*.png' -o -iname '*.jpg' -type f -maxdepth 1`
do
new=image-$count.${img##*.}
echo "Renaming $img to $new"
mv "$img" "$new"
let count++
done
C 版本rename:rename .JPG .jpg *.JPG,即把所有.JPG文件從.JPG改為.jpg。
Perl 版本rename:rename *.JPG *.jpg。所有文件的空格全部替換為下劃線rename 's/ /_/g' *。大寫轉(zhuǎn)小寫rename 'y/A-Z/a-z/' *。
- 精確檢查單詞是否在詞典文件
words中:
#!/bin/bash
word=$1
grep "^$1$" /usr/share/dict/words -q
if [ $? -eq 0 ]; then
echo $word is a dictionary word.
else
echo $word is not a dictionary word.
fi
其中,^和$標記單詞的開始和結(jié)束。-q禁止任何輸出?;蛘?/p>
#!/bin/bash
word=$1
output=`echo \"$word\" | aspell list`
if [ -z $output ]; then
echo $word is a dictionary word.
else
echo $word is not a dictionary word.
fi
look查詢特定字符串開頭的行:look string file。file必須是經(jīng)過排序的,否則無效。expect可用于實現(xiàn)自動交互,不再手動輸入。利用多核并行:
#!/bin/bash
PIDARRAY=()
for file in File1.iso File2.iso
do
md5sum $file &
PIDARRAY+=("$!")
done
wait ${PIDARRAY[@]}
&將命令置于后臺運行。$!獲得最近一個后臺進程 PID。wait等待進程結(jié)束。
第3章 以文件之名
創(chuàng)建特定大小的文件:
dd if=/dev/zero of=junk.data bs=1c/w/b/k/M/G count=1。
如果bs=2M count=2,則文件大小為 4M。of=一定要仔細檢查。
dd命令可用于測量內(nèi)存的操作速度。兩個經(jīng)過排序的文件的比較:
comm A.txt B.txt。輸出第一列為只在A.txt中的行,第二列為只在B.txt中的行,第三列為二者共有的行。只打印第三列在末尾加參數(shù)-1 -2。刪除當前文件夾下的重復(fù)文件:
#!/bin/bash
# ls -lS --time-style=long-iso | awk 'BEGIN {
# getline; getline
ls -lS --time-style=long-iso | grep ^- | awk 'BEGIN {
getline
name1=$8; size=$5
}
{
name2=$8
if ( size==$5 )
{
"md5sum " name2 | getline; csum2=$1;
"md5sum " name1 | getline; csum1=$1;
if ( csum1==csum2 )
{
print name1; print name2
}
}
else
{
size=$5
}
name1=name2
}' | sort -u > duplicate_files
cat duplicate_files | xargs -I {} md5sum {} | sort | uniq -w 32 | awk '{print $2}' | sort -u > duplicate_sample
echo Removing...
comm duplicate_files duplicate_sample -2 -3 | tee /dev/stderr | xargs rm
rm duplicate_files duplicate_sample
echo Removed duplicates files successfully.
若含csum2=$1和csum1=$1的兩行交換位置,則運行結(jié)果錯誤,原因不明。
setuid 只能用于 Linux ELF 格式二進制文件,不能用于腳本文件。
root 用戶可設(shè)置文件不可修改:
chattr +i file。任何用戶均可查看lsattr。touch更改文件時間:-a只更改訪問時間,-m只更改修改時間,-d同時更改訪問和修改時間。顯示符號鏈接指向的路徑:
readlink。統(tǒng)計文件信息:
!/bin/bash
if [ $# -ne 1 ]
then
echo "Usage is $0 basepath"
exit
fi
path=$1
declare -A statarray
while read line
do
ftype=`file -b "$line" | cut -d , -f 1`
let statarray["$ftype"]++
done < <(find $path -type f -print)
echo ======== File types and counts ========
for ftype in "${!statarray[@]}"
do
echo $ftype : ${statarray["$ftype"]}
done
其中,$#是傳遞給腳本的參數(shù)個數(shù),$0是腳本自己的名字,$1是傳給腳本的第一個參數(shù),file -b只打印文件類型,cut -d , -f 1選取以逗號分隔的第一列數(shù)據(jù),<(find $path -type f -print)獲取子進程輸出數(shù)據(jù)流。Bash 3.0 及更高版本中,亦可用done <<< "`find $path -type f -print`"。
- 環(huán)回文件系統(tǒng)的創(chuàng)建和使用:
dd if=/dev/zero of=loopbackfile.img bs=1G count=1
mkfs.ext4 loopbackfile.img
mkdir /mnt/loopback
mount -o loop loopbackfile.img /mnt/loopback
umount /mnt/loopback
分區(qū):
losetup /dev/loop1 loopbackfile.img
fdisk /dev/loop1
losetup -o 32256 /dev/loop2 loopbackfile.img
或使用:
kpartx -v -a loopbackfile.img
mount /dev/mapper/loop0p1 /mnt/loopback1
kpartx -d loopbackfile.img
將對掛載設(shè)備的更改即刻寫入物理設(shè)備:sync。
從光盤創(chuàng)建鏡像:
cat /dev/cdrom > image.iso,最好還是用dd if=/dev/cdrom of=image.iso。
從文件創(chuàng)建鏡像:mkisofs -V "Label" -o image.iso source_dir/。
生成可引導(dǎo)的混合型 ISO:isohybrid image.iso。
刻錄 ISO:cdrecord -v dev=/dev/cdrom image.iso -speed 8。多次刻錄:-multi。
開關(guān)光驅(qū)托盤:eject和eject -t。生成修補文件:
diff -u version1.txt version2.txt > version.patch。
修補:patch -p1 version1.txt < version.patch。
撤銷:再執(zhí)行一次上一條命令。生成目錄的差異信息:
diff -Naur directory1 directory2。打印前 M 行:
head -n M file。
打印除后 M 行之外的所有行:head -n -M file。
打印后 M 行:tail -n M file。
打印除前 M 行之外的所有行:tail -n +(M+1) file。關(guān)注文件的變化:
tail -f file。
隨進程結(jié)束而結(jié)束關(guān)注:tail -f file --pid $PID。列出當前目錄下的目錄:
ls -d */,ls -F | grep /$,ls -ls | grep ^d,find . -type d -maxdepth 1 -print。命令行中的目錄切換:
pushd,在棧中壓入目錄并切換;dirs顯示棧中的目錄;pushd +num,切換到棧中的第num個目錄,從0開始;popd刪除當前目錄并進入切換前的目錄;popd +num刪除指定目錄。統(tǒng)計行數(shù)、單詞數(shù)、字符數(shù):
wc,分別統(tǒng)計wc -l/w/c。打印文件中最長一行的長度wc -L。以樹狀結(jié)構(gòu)打印文件和目錄:
tree PATH。重點標記符合某樣式的文件tree PATH -P PATTERN。重點標記除某樣式外的文件tree PATH -I PATTERN。同時打印文件和目錄的大小tree -h PATH。以 HTML 形式輸出目錄樹tree PATH -H http://localhost -o out.html。
第4章 讓文本飛
正則表達式的基本組成部分:
^行首標記,$行尾標記,.匹配任意一個字符,[]匹配包含在方括號內(nèi)的任意一個字符,[^]匹配除方括號內(nèi)的任意一個字符,[-]匹配指定范圍內(nèi)的任意一個字符,?匹配之前的項1次或0次,+匹配之前的項至少1次,*匹配之前的項至少0次,()創(chuàng)建用于匹配的子串,{n}匹配之前的項 n 次,{n,}匹配之前的項至少 n 次,{n,m}匹配之前的項最少 n 次、最多 m 次,|匹配兩邊的任意一項,\將前述特殊字符轉(zhuǎn)義。著重標記匹配的字符串:
grep string filename --color=auto。
使用擴展正則表達式:grep -E或egrep。
只輸出匹配的文本:egrep -o。
打印匹配行之外的所有行:grep -v。
統(tǒng)計匹配行數(shù):grep -c。同一行內(nèi)有多處匹配時,僅算一次。統(tǒng)計匹配的次數(shù)可結(jié)合egrep -o和wc -l。
打印匹配行的行號:grep -n。
打印字符串的字符偏移:grep -bo。從整個文本的第一字符算起,起始值為0。
打印包含匹配字符串的文件:grep -l,不包含的文件grep -L。
遞歸搜索:grep -R。
忽略大小寫:grep -i。
多字符串匹配:grep -e string1 -e string2。將每個字符串寫入文件的每一行,根據(jù)文件搜索grep -f。
指定文件搜索:grep "main()" . -r --include *.{c,cpp}。
排除文件搜索:grep "main()" . -r --exclude "README"。
排除目錄:--exclude-dir。
從文件中讀取排除的文件列表:--exclude-from。
輸出以0值字節(jié)作為終結(jié)符的文件名:grep -lZ。
靜默輸出:-q。匹配成功返回0,失敗返回非0。
打印匹配行及其后的 n 行:grep -A n,之前-B n,前后各 n 行-C n。若有多行匹配,以--分隔。按列打?。?code>cut -f num file,多列
num1,num2,num3...。
排除不含定界符的行:-s。
打印除某列外的所有行:cut -f num --complement file。
指定定界符:-d。
按字符或字節(jié)選?。?code>-c或-b,提取多字段時必須指定輸出定界符cut -c 0-2,4-6 --output-delimiter " "。打印替換后的文本:
sed 's/text/replace/' file。定界符/可任意更換,如,,|,:等等。
替換并保存:-i,此時不打印;同時保留副本-i.bak。
全行替換:sed 's/text/replace/g' file。
全行第 n 處開始替換:sed 's/text/replace/ng' file。
移除空白行:sed '/^$/d' file。
替換所有的三位數(shù):sed 's/\b[0-9]\{3\}\b/NUMBER/g' file。\b表示字符串邊界。
所有單詞放入中括號內(nèi):sed 's/\w\+/[&]/g。\w\+匹配每一個單詞,&對應(yīng)匹配字符串。
大小寫子串互換位置:sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'。
多個替換:sed 's/a/A/' | sed 's/c/C/'或sed 's/a/A/; s/c/C/'或sed -e 's/a/A/' -e 's/c/C/'。
使用變量需要雙引號:sed "s/$text/replace/"。awk基本結(jié)構(gòu):awk 'BEGIN{ commands } pattern { commands } END{ commands }' file。首先執(zhí)行BEGIN語句塊;之后如果滿足pattern的條件則執(zhí)行其后的語句塊,如未提供pattern則默認執(zhí)行,循環(huán)執(zhí)行直到輸入流讀取完畢;最后執(zhí)行END語句塊。
NR:當前行號。
NF:當前行的字段數(shù)。
$0:當前行的文本內(nèi)容。
傳遞外部變量:awk -v VARIABLE=$VAR,或awk '{ commands }' VARIABLE=$VAR。
在BEGIN語句塊中讀取輸入流可以使用getline。
pattern過濾:NR < 5行號小于5的行,NR==1, NR==5行號在1到5之間的行,/string/包含 string 的行,!/string/不包含 string 的行,/string1/, /string2/包含 string1 的行到包含 string2 的行。
指定定界符:awk -F或BEGIN{ FS=" " },定界符|替換為換行符BEGIN{ RS="|" },換行符替換為定界符BEGIN{ ORS="|" },指定輸出分隔符BEGIN{ OFS="|" }。
字符串控制函數(shù):length(string),index(string, search_string),split(string, array, delimiter),substr(string, start-position, end-position),sub(regex, replacement_str, string),gsub(regex, replacement_str, string),match(regex, string)。統(tǒng)計詞頻:
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Usage is $0 filename"
exit -1
fi
filename=$1
egrep -o "\b[[:alpha:]]+\b" $filename | \
awk '{ count[$0]++ }
END { printf("%-14s%s\n", "Word", "Count");
for( ind in count )
{ printf("%-14s%d\n", ind, count[ind]) }
}'
按列拼接文件:
paste,-d指定定界符。按行逆序打?。?code>tac,
-s替換換行符。
awk '{ lifo[NR]=$0 }
END { for ( lno=NR; lno > 0; lno-- ) { print lifo[lno] } }' file
提取電子郵件地址:
egrep -o '[A-Za-z0-9._]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}'。
提取 HTTP URL:egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}"。替換變量中的文本:
${var/string/replace/}。
生成變量子串:${var:start_position:length}。
第5章 一團亂麻?沒這回事
下載網(wǎng)頁:
wget URL1 URL2 URL3 ...。
下載文件:wget -t 0 ftp://example_domain.com/somefile -O downloaded_file -o log。-O重命名,-o將輸出重定向至 log 文件,-t 0不斷重試。
限速:--limit-rate 20k/m。
限制最大磁盤配額:--quota或-Q。
斷點續(xù)傳:重新下載時使用wget -c。
復(fù)制網(wǎng)站:wget --mirror --convert-links URL,或wget -r -N -k -l depth URL。
輸入用戶名和密碼:wget --user username --password pass URL,手動輸入密碼--ask-password。將網(wǎng)頁內(nèi)容以 ASCII 編碼的形式存儲到文件中:
lynx URL -dump > webpage_as_text.txt。下載數(shù)據(jù)寫入文件:
curl URL -o filename --progress。
斷點續(xù)傳:curl -C - URL。
從特定的文件偏移處下載:curl URL/file -C offset。
設(shè)置參照頁:curl --referer referer_URL target_URL。
第6章 B 計劃
歸檔:
tar -cf output.tar file1 file2 file3 ...。
列出歸檔的文件:tar -tf output.tar,或冗長模式tar -tvf。
追加文件:tar -rf output.tar new_file。
提?。?code>tar -xf output.tar,指定目錄tar -xf output.tar -C path。
提取特定文件:tar -xf output.tar file1 file4。
打包傳輸:tar -cvf - local_path | ssh user@example.com "tar -xv -C remote_path。
拼接:tar -Af output1.tar output2.tar。
追加更新的文件:tar -uf output.tar file1,提取時會選最新的。
判斷歸檔文件與本地同名文件是否相同:tar -df output.tar。
刪除:tar -f ouput.tar --delete file1 file2。
壓縮:-jzip2 格式,-zgzip 格式,--lzmalzma 格式。
根據(jù)擴展名自動壓縮:-a。
歸檔時排除指定文件:tar -cf output.tar * --exclude "*.txt",或根據(jù)文件tar -cf output.tar * -X file。
排除版本控制相關(guān)的文件和目錄:--exclude-vcs。
打印總歸檔字節(jié)數(shù):--totals。保留所有文件屬性的歸檔:
echo file1 file2 file3 | cpio -ov > archive.iso。
列出歸檔的內(nèi)容:cpio -it < archive.iso。
提?。?code>cpio -id < archive.cpio。
cpio提取至絕對路徑,tar提取至相對路徑。壓縮:
gzip file。
解壓:gunzip file.gz。
列出:gzip -l file.gz。
指定輸出文件:-c >。
最低壓縮比--fast或-1,最高壓縮比--best或-9。
直接讀?。?code>zcat file.gz。
另有bzip2/bunzip2、lzma/unlzma。歸檔并壓縮
zip,提取unzip不會刪除源文件。
遞歸-r,更新-u,刪除-d,列出-l。利用多核歸檔并壓縮:
tar -c directory_to_compress | pbzip2 -c > output.tar。
解壓并提?。?code>pbzip2 -dc output.tar | tar -x。
指定核數(shù):-p。
指定壓縮比:-1至-9。超高的壓縮率,且無須解壓即可讀取少量文件,使用 squashfs 只讀文件系統(tǒng)。
創(chuàng)建:mksquashfs SOURCES compressedfs.squashfs。
利用環(huán)回方式掛載:mount -o loop compressedfs.squashfs /mnt/squash。
創(chuàng)建時排除部分文件:-e,或根據(jù)文件-ef,使用通配符-wildcards。歸檔并壓縮傳輸:
rsync -avz source destination。路徑最后有/和沒有是不同的。
排除部分文件:--exclude,或根據(jù)文件--exclude-from。
刪除不存在的文件:--delete。版本控制:
在備份端的備份目錄中執(zhí)行git init --bare;
在源端的源目錄中添加編輯者信息git config --global user.name "FirstName FamilyName",git config --global user.email "username@somewhere.com";
在源目錄中執(zhí)行git init,git commit --allow-empty -am "Init";
備份git remote add origin user@backuphost:backup_path,git push origin master;
添加到備份列表git add,從備份列表中刪除git rm;
標注檢查點git commit -m "Commit Message";
查看所有版本git log;
恢復(fù)至某版本git checkout ID;
修復(fù)git clone user@backuphost:backup_path。創(chuàng)建文件系統(tǒng)/分區(qū)備份:
fsarchiver savefs backup.fsa /dev/sda1 /dev/sda2。
恢復(fù)分區(qū):fsarchiver restfs backup.fsa id=0,dest=/dev/sda1 id=1,dest=/dev/sdb1。id=0表示提取第一個分區(qū)的內(nèi)容。
第7章 無網(wǎng)不利
MAC 地址欺騙:
ifconfig eth0 hw ether new_MAC。重啟后失效。列出域名的所有 IP 地址:
host google.com。
同時列出 DNS 資源記錄:nslookup google.com。設(shè)置默認網(wǎng)關(guān):
route add default gw IP INTERFACE。查看途經(jīng)的網(wǎng)關(guān):
traceroute google.com。找出網(wǎng)絡(luò)上所有的活動主機:
#!/bin/bash
for ip in 172.17.110.{1..255}
do
(
ping $ip -c 2 &> /dev/null
if [ $? -eq 0 ]
then
echo $ip is alive.
fi
)&
done
wait
或者使用fping -a 172.17.110.1/24 -g 2> /dev/null或fping -a 172.17.110.0.1 172.17.110.255 -g。
指定 SSH 端口:
ssh user@remotehost -p 422。
遠程執(zhí)行,本地顯示:ssh user@remotehost 'command1; command2; command3'。
壓縮傳輸:-C。FTP 連接:
sftp user@remotehost。上傳put,下載get。
指定端口:-oPort=PortNumber。scp -p將保留文件的權(quán)限和模式。SSH 自動化認證:
創(chuàng)建密鑰,指定加密算法為 RSAssh-keygen -t rsa;
上傳至遠程主機ssh user@remotehost "cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_rsa.pub或ssh-copy-id user@remotehost。將本地主機端口8000上的流量轉(zhuǎn)發(fā)到 www.kernel.org 的端口80上:
ssh -L 8000:www.kernel.org:80 user@localhost。
將遠程主機端口8000上的流量轉(zhuǎn)發(fā)到 www.kernel.org 的端口80上:
ssh -L 8000:www.kernel.org:80 user@REMOTE_MACHINE。
非交互式:ssh -fL 8000:www.kernel.org:80 user@localhost -N。-f執(zhí)行命令前轉(zhuǎn)入后臺,-N說明無需執(zhí)行命令。
反向端口轉(zhuǎn)發(fā):ssh -R 8000:localhost:80 user@REMOTE_MACHINE。在本地掛載點上掛載遠程驅(qū)動器:
sshfs -o allow_other user@remotehost:remote_path /mnt/mountpoint。列出開放端口及運行的服務(wù):
lsof -i或netstat -tnp。在本地端口 1234 創(chuàng)建套接字
nc -l 1234,連接到該套接字nc HOST 1234,可相互發(fā)送信息。
文件傳輸:在接收端執(zhí)行nc -l 1234 > destination_file,在發(fā)送端執(zhí)行nc HOST 1234 < source_file。創(chuàng)建無線熱點:
#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -i $1 -o $2 -s 10.99.0.0/16 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE
運行./netsharing.sh eth0 wlan0。
- 阻塞發(fā)送到特定 IP 的流量:
iptables -A OUTPUT -d 8.8.8.8 -j DROP。
阻塞發(fā)送到特定端口的流量:iptables -A OUTPUT -p tcp -dport 21 -j DROP。
-A添加規(guī)則到OUTPUT規(guī)則鏈中。
清除所有改動:iptables --flush。
第8章 當個好管家
打印文件或目錄占用的磁盤空間:
du。
打印目錄中每個文件占用的空間:-a。
默認以字節(jié)為單位,標準容量單位-h。
指定字節(jié) / KB / MB / 塊為單位:-b/k/m/B。
打印總計:-c,只打印總計-s。
排除部分文件:--exclude,或根據(jù)文件--exclude-from。
指定深度:--max-depth。
排除所有掛載點:-x。
找出大文件:find . -type f -exec du -k {} \; | sort -nrk 1 | head。磁盤可用空間:
df -h。打印運行時間:
time COMMAND。
統(tǒng)計信息寫入文件:/usr/bin/time -o output COMMAND,不覆蓋而是追加至 output-a。
格式化輸出:-f "FORMAT STRING"。real 時間%e,user 時間%U,sys 時間$S。此外還有很多可用參數(shù)。當前登錄用戶:
who,w,users。查看加電運行時間:
uptime。上一次啟動及登錄信息:
last,指定記錄日志-f。
指定用戶:last USER。
指定會話:last reboot。
失敗的用戶登錄會話信息:lastb。統(tǒng)計一小時內(nèi)占用 CPU 最多的十個進程:
#!/bin/bash
SECS=3600
UNIT_TIME=60
STEPS=$(( $SECS / $UNIT_TIME ))
echo Watching CPU usage...
for (( i=0; i<STEPS; i++ ))
do
ps -eo comm,pcpu | tail -n +2 >> /tmp/cpu_usage.$$
sleep $UNIT_TIME
done
echo
echo CPU eaters :
cat /tmp/cpu_usage.$$ | \
awk '{process[$1] += $2 }
END{
for ( i in process )
{
printf("%-20s %s\n", i, process[i])
}
}' | sort -nrk 2 | head
rm /tmp/cpu_usage.$$
comm表示命令名,pcpu表示 CPU 使用率,$$是腳本的進程 ID。
以固定間隔監(jiān)視命令輸出:
watch。
指定間隔秒數(shù):-n。默認為兩秒。
突出差異:-d。監(jiān)視目錄訪問:
#!/bin/bash
path=$1
inotifywait -m -r -e create,move,delete $path -q
持續(xù)監(jiān)視變化-m,遞歸-r,指定需用監(jiān)視的事件-e。
logrotate配置文件參數(shù):
missingok日志文件丟失則忽略,然后返回;
notifyempty僅當源日志文件非空時才對其進行輪替;
size限制日志文件的大??;
compress壓縮舊日志;
weekly輪替時間間隔;
rotate保留的舊日志文件的歸檔數(shù)量;
create 0600 root root指定權(quán)限和屬性。重要的應(yīng)用程序應(yīng)將執(zhí)行過程記錄在日志文件中。Linux
/var/log的重要日志文件包括:
boot.log系統(tǒng)啟動信息;
httpdApache Web服務(wù)器日志;
messages發(fā)布內(nèi)核啟動信息;
auth.log用戶認證日志;
dmesg系統(tǒng)啟動信息;
mail.log郵件服務(wù)器日志;
Xorg.0.logX 服務(wù)器日志。向
/var/log/messages中寫入日志信息:logger MESSAGE。特定標記-t。寫入另一日志文件的最后一行-f。檢測入侵:
#!/bin/bash
AUTHLOG=/var/log/secure
if [[ -n $1 ]];
then
AUTHLOG=$1
echo Using Log file : $AUTHLOG
fi
LOG=/tmp/valid.$$.log
grep -v "invalid" $AUTHLOG > $LOG
users=$(grep "Failed password" $LOG | awk '{ print $(NF-5) }' | sort | uniq)
printf "%-5s|%-10s|%-10s|%-13s|%-33s|%s\n" "Sr#" "User" "Attempts" "IP address" "Host_Mapping" "Time range"
ucount=0
ip_list="$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" $LOG | sort | uniq)"
for ip in $ip_list
do
grep $ip $LOG > /tmp/temp.$$.log
for user in $users
do
grep $user /tmp/temp.$$.log > /tmp/$$.log
cut -c -16 /tmp/$$.log > $$.time
tstart=$(head -1 $$.time)
start=$(date -d "$tstart" "+%s")
tend=$(tail -1 $$.time)
end=$(date -d "$tend" "+%s")
limit=$(( $end - $start ))
if [ $limit -gt 120 ]
then
let ucount++
IP=$(egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /tmp/$$.log | head -1)
TIME_RANGE="$tstart-->$tend"
ATTEMPTS=$(cat /tmp/$$.log | wc -l)
HOST=$(host $IP | awk '{ print $NF }')
printf "%-5s|%-10s|%-10s|%-10s|%-33s|%-s\n" "$ucount" "$user" "$ATTEMPTS" "$IP" "$HOST" "$TIME_RANGE"
fi
done
done
rm /tmp/valid.$$.log /tmp/$$.log $$.time /tmp/temp.$$.log 2> /dev/null
排除不存在的用戶名grep -v "invalid"。
- 監(jiān)視遠程磁盤健康狀況:
#!/bin/bash
logfile="diskusage.log"
if [[ -n $1 ]];
then
logfile=$1
fi
if [ ! -e $logfile ]
then
printf "%-8s %-14s %-9s %-8s %-6s %-6s %-6s %s\n" "Date" "IP address" "Device" "Capacity" "Used" "Free" "Percent" "Status" > $logfile
fi
ip_list="10.0.0.1 10.0.0.2"
(
for ip in $ip_list
do
ssh kangk@$ip 'df -H' | grep ^/dev/ > /tmp/$$.df
while read line
do
cur_date=$(date +%D)
printf "%-8s %-14s " $cur_date $ip
echo $line | awk '{ printf("%-9s %-8s %-6s %-6s %-8s", $1,$2,$3,$4,$5) }'
pusg=$(echo $line | egrep -o "[0-9]+%")
pusg=${pusg/\%/}
if [ $pusg -lt 80 ]
then
echo SAFE
else
echo ALERT
fi
done < /tmp/$$.df
done
echo
) >> $logfile
電源使用的測量與優(yōu)化:
powertop。生成 HTML 格式的報表--html。I/O 監(jiān)視:
iotop。只顯示正在進行-o,非交互式打印兩次-b -n 2,特定進程-p `pidof command`。檢查磁盤:
fsck。檢查所有/etc/fstab中的-A。自動修復(fù)-a。模擬操作-AN。
第9章 管理重任
列出占用 CPU 最多的10個進程:
ps -eo comm,pcpu --sort -pcpu | head。
指定有效用戶:-u。
指定真實用戶:-U。
指定 TTY:-t。
輸出線程相關(guān)信息:-L。
列出依賴的環(huán)境變量:ps -eo cmd e。列出進程的所有 PID :
pgrep command。
指定定界符:-d。
指定用戶:-u。列出所有可用的進程信號:
kill -l。
發(fā)送指定信號:kill -s SIGNAL PID。
常用信號:SIGHUP 1,SIGINT 2,SIGKILL 9,SIGTERM 15,SIGTSTP 20。
通過命令名:killall。
捕捉并響應(yīng)信號:trap 'signal_handler_function_name' SIGNAL_LIST。