第1章 小試牛刀
$ 是普通用戶,# 表示管理員用戶 root。
shebang:
#!
跨新。sharp / hash / mesh 稱呼 #休里,bang 稱呼 !蛆挫。后接解釋器命令路徑。兩種運(yùn)行腳本方式:作為命令行參數(shù)(無(wú)需 shebang)妙黍,或授予腳本執(zhí)行權(quán)限悴侵。
echo
后無(wú)引號(hào)或使用單引號(hào),無(wú)須轉(zhuǎn)義字符\
拭嫁;雙引號(hào)中使用轉(zhuǎn)義字符須使用-e
可免;無(wú)引號(hào)時(shí)后面的文本中不能有;
;變量替換在單引號(hào)中無(wú)效做粤。printf
不像echo
會(huì)自動(dòng)添加換行符浇借。取消echo
自動(dòng)添加換行符須使用-n
。%[-][n]s
怕品,-
為左對(duì)齊妇垢,n
為字符串內(nèi)的字符數(shù),如n
小于命令后對(duì)應(yīng)的字符串長(zhǎng)度,則n
被忽略闯估。打印紅色文本灼舍,
echo -e "\e[1;31m This is red text. \e[0m"
。\e[1;31m
將顏色設(shè)為紅色涨薪,\e[0m
將顏色重置回骑素。常用背景顏色代碼:重置=0,黑色=30尤辱,紅色=31砂豌,綠色=32,黃色=33光督,藍(lán)色=34阳距,洋紅=35,青色=36结借,白色=37筐摘。常用背景顏色代碼:重置=0,黑色=40船老,紅色=41咖熟,綠色=42,黃色=43柳畔,藍(lán)色=44馍管,洋紅=45,青色=46薪韩,白色=47确沸。Bash 中每一個(gè)變量的值都是字符串。
進(jìn)程的環(huán)境變量可用
cat /proc/$PID/environ
得到俘陷,PID/environ | tr '\0' '\n'```每行顯示一個(gè)拉盾,更清楚桨菜。var=value
是賦值操作,var = value
是相等操作捉偏。獲取字符串長(zhǎng)度
${#var}
倒得。當(dāng)前使用 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 ))
,三者等價(jià)挤巡。等號(hào)后的變量名前加$
亦可剩彬。高精度計(jì)算:
echo "scale=16; $no1 ^ $no2" | bc
。此處 no2 必須為整數(shù)矿卑。重定向 stdin:
0>(>)
喉恋。重定向 stdout:1>(>)
。重定向 stderr:2>(>)
母廷。tee
屏顯加保存轻黑,僅保存 stdout椭岩。有-a
為追加內(nèi)容移迫,沒(méi)有為覆蓋。將 out 的內(nèi)容寫入 log.txt:
out 文件內(nèi)容:
#!/bin/bash
cat << EOF > log.txt
hi
hello
EOF
運(yùn)行 . 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ù)組長(zhǎng)度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
耗啦。尤其對(duì)于特權(quán)命令,可避免攻擊者使用別名盜取信息驯遇。獲取終端行數(shù)和列數(shù):
tput culs
芹彬,tput lines
蓄髓。
打印出當(dāng)前終端名:tput longname
叉庐。
將光標(biāo)移到坐標(biāo)(10,10)處:tput cup 10 10
会喝。
設(shè)置終端背景色:tput setb n
陡叠。n 可在0至7之間取值。
設(shè)置終端前景色:tput setf n
肢执。
設(shè)置粗體:tput bold
枉阵。
設(shè)置下劃線:tput smul
。
刪除從當(dāng)前光標(biāo)位置以后的所有內(nèi)容:tput ed
预茄。禁止將輸出發(fā)送到終端:
#!/bin/bash
echo -e "Enter password: "
stty -echo
read password
stty echo
echo
echo Password read.
紀(jì)元時(shí)或 Unix 時(shí)間:自世界標(biāo)準(zhǔn)時(shí)間(UTC)1970年1月1日0時(shí)0分0秒起所流逝的秒數(shù)兴溜。
當(dāng)前紀(jì)元時(shí):
date +%s
侦厚。
日期串轉(zhuǎn)換成紀(jì)元時(shí):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 "格式化的日期字符串"
膘怕。倒計(jì)時(shí):
#!/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í)行時(shí)顯示:-x
。讀取時(shí)顯示:-v
岛心。
#!/bin/bash
改為#!/bin/bash -xv
来破,則直接運(yùn)行即可。
自定義調(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ù)名徘禁。可通過(guò)ulimit -u 128
(暫時(shí))或修改配置文件 /etc/security/limits.conf 來(lái)限制可生成的最大進(jìn)程數(shù)來(lái)避開(kāi)髓堪。
導(dǎo)出函數(shù):
export -f fname
晌坤。退出狀態(tài):
$?
。成功則為0旦袋,否則為非0骤菠。如果最后設(shè)置了exit n
,則總返回 n疤孕。子 shell 法:
cmd_output=$(ls | cat -n)
商乎。
反引用或反標(biāo)記法:cmd_output=`ls | cat -n`
。
保留空格和換行符:echo "$cmd_output"
祭阀。使用子 shell
()
:
pwd
(cd /bin; ls)
pwd
子 shell 中的命令對(duì)當(dāng)前 shell 沒(méi)有影響鹉戚。
讀取 n 個(gè)字符并存入變量:
read -n number_of_chars variable_name
。
用無(wú)回顯的方式讀取密碼:read -s var
专控。
顯示提示信息:read -p "xxx" var
抹凳。
在特定時(shí)限內(nèi)讀取輸入:read -t timeout var
。
用特定的定界符作為輸入行的結(jié)束:read -d ":" var
伦腐。含延時(shí)重復(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
。使用字符串比較時(shí)咳焚,最好用雙中括號(hào)洽损,因?yàn)閱沃欣ㄌ?hào)有時(shí)回產(chǎn)生錯(cuò)誤。用
test
可以避免使用過(guò)多的括號(hào)革半。
第2章 命令之樂(lè)
壓縮相鄰空白行:
cat -s file
碑定。
將制表符顯示為^I
:cat -T file
流码,對(duì)排除縮進(jìn)錯(cuò)誤非常有用。
顯示行號(hào):cat -n file
延刘,空白行不標(biāo)號(hào)則用-b
旅掂。錄制終端會(huì)話:
script -t 2> timing.log -a output.session
,之后進(jìn)行命令行操作访娶,以exit
結(jié)束錄制商虐。
播放:scriptreplay timing.log output.session
。find .
類似ls
崖疤。find . -print0
將以 NULL 取代空格作為分隔符秘车,在文件名中含空格時(shí)有用。
忽略字母大小寫:find path -iname
劫哼。
匹配多個(gè)條件中的一個(gè):\( -name "*.txt" -o -name "*.pdf" \)
叮趴。
同時(shí)搜索文件和文件夾:-path
。
正則表達(dá)式搜索:-regex
或忽略大小寫-iregex
权烧。
否定參數(shù):! -name
眯亦。
限制目錄深度:最大深度-maxdepth
,開(kāi)始的最小深度-mindepth
般码。這個(gè)選項(xiàng)應(yīng)該放在最前面妻率,以避免多余的搜索。
按類型搜索:-type f/l/d/c/b/s/p
板祝。
按時(shí)間搜索:最近7天內(nèi)訪問(wèn)過(guò)-atime -7
宫静,恰好7天前修改過(guò)-mtime 7
,超過(guò)7天前變化過(guò)-ctime +7
券时。如計(jì)量時(shí)間為分鐘孤里,則用-amin/-mmin/-cmin
。比參考文件更新-newer file_to_be_compared
橘洞。
按大小搜索:-size nb/c/w/k/M/G
捌袜。
刪除找到的文件:在最后加-delete
。
按特定權(quán)限搜索:-perm
炸枣。
按所有權(quán)搜索:-user
虏等。
對(duì)搜索到的文件執(zhí)行命令:-exec command/batch_file {} \;
。{}
將替換為搜索到的文件名抛虏。\;
表示命令結(jié)束博其。{} +
可減少命令運(yùn)行次數(shù)套才。
跳過(guò)特定的目錄:find . \( -name ".git" -prune \) -o \( -type f -print \)
迂猴。多行輸入轉(zhuǎn)單行輸出:
cat example.txt | xargs
。
單行輸入轉(zhuǎn)多行輸出:cat example.txt | xargs -n 3
背伴。此處每行3個(gè)參數(shù)沸毁。
指定定界符:xargs -d
峰髓。默認(rèn)為空格。
固定格式選項(xiàng):cat args.txt | xargs -I {} command/batch_file -p {} -l
息尺。args.txt
中有幾個(gè)參數(shù)携兵,命令就會(huì)執(zhí)行幾次。
統(tǒng)計(jì)目錄中所有 C 程序文件的行數(shù):find . -type f -name "*.c" -print0 | xargs -0 wc -l
搂誉。必須使用-print0
和-0
徐紧,因文件名中可能包含空格。
對(duì)同一參數(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'
。
刪除補(bǔ)集之外的所有字符: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
愈涩。輸出校驗(yàn)和到文件:
md5sum file1 file2 ... > file_sum.md5
。
校驗(yàn):md5sum -c *.md5
加矛。須與被校驗(yàn)文件在同一目錄下履婉。
sha1sum
用法同md5sum
。二者均為單向散列算法斟览,無(wú)法逆推出原始數(shù)據(jù)谐鼎,是存儲(chǔ)密碼的理想方案。但是由于計(jì)算能力攀升使其容易破解趣惠,推薦使用bcrypt
或sha512sum
狸棍。
輸出整個(gè)目錄的校驗(yàn)和: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
。
按第二列的第二個(gè)字符至第四個(gè)字符排序:sort -k 2.2,2.4
弹灭。
后接xargs
對(duì)行做操作時(shí)用:sort -z file | xargs -0 command
督暂。
重復(fù)的行僅輸出一次:sort file | uniq
揪垄。僅輸出不重復(fù)的行:uniq -u
。統(tǒng)計(jì)出現(xiàn)次數(shù)uniq -c
逻翁。顯示重復(fù)的行uniq -d
饥努。創(chuàng)建臨時(shí)文件:
filename=`mktemp`
。
創(chuàng)建臨時(shí)目錄:dirname=`mktemp -d`
八回。
生成臨時(shí)文件名:tmpfile=`mktemp -u`
酷愧。
按模板創(chuàng)建:mktemp tmp_model.xxx
。至少3個(gè) xxx缠诅。按大小或行數(shù)等分割文件:
split
伟墙。
按內(nèi)容分割文件:csplit file /SpecificWord/ -n 2 -s {*} -f filename -b "%02d.suffix"
。-s
為靜默模式滴铅。{*}
表示重復(fù)進(jìn)行直到文件結(jié)束戳葵;若*
為數(shù)字,表示進(jìn)行分割的次數(shù)汉匙。-n
指定分割后-f
指定的文件名filename
后的數(shù)字個(gè)數(shù)拱烁。-b
指定filename
后的數(shù)字格式及后綴。提取文件名和擴(kuò)展名:
file="sample.jpg"
name=${file%.*}
extension=${file#*.}
%
從右向左找最短匹配并刪除噩翠,%%
找最長(zhǎng)匹配并刪除戏自。#
和##
則從左向右找。
- 批量重命名:
#!/bin/bash
# 將當(dāng)前目錄下的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
其中,^
和$
標(biāo)記單詞的開(kāi)始和結(jié)束狞洋。-q
禁止任何輸出弯淘。或者
#!/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
查詢特定字符串開(kāi)頭的行:look string file
吉懊。file
必須是經(jīng)過(guò)排序的庐橙,否則無(wú)效。expect
可用于實(shí)現(xiàn)自動(dòng)交互借嗽,不再手動(dòng)輸入态鳖。利用多核并行:
#!/bin/bash
PIDARRAY=()
for file in File1.iso File2.iso
do
md5sum $file &
PIDARRAY+=("$!")
done
wait ${PIDARRAY[@]}
&
將命令置于后臺(tái)運(yùn)行。$!
獲得最近一個(gè)后臺(tái)進(jìn)程 PID恶导。wait
等待進(jìn)程結(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=
一定要仔細(xì)檢查羽戒。
dd
命令可用于測(cè)量?jī)?nèi)存的操作速度缤沦。兩個(gè)經(jīng)過(guò)排序的文件的比較:
comm A.txt B.txt
虎韵。輸出第一列為只在A.txt
中的行,第二列為只在B.txt
中的行缸废,第三列為二者共有的行包蓝。只打印第三列在末尾加參數(shù)-1 -2
。刪除當(dāng)前文件夾下的重復(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
的兩行交換位置企量,則運(yùn)行結(jié)果錯(cuò)誤测萎,原因不明。
setuid 只能用于 Linux ELF 格式二進(jìn)制文件届巩,不能用于腳本文件硅瞧。
root 用戶可設(shè)置文件不可修改:
chattr +i file
。任何用戶均可查看lsattr
恕汇。touch
更改文件時(shí)間:-a
只更改訪問(wèn)時(shí)間腕唧,-m
只更改修改時(shí)間,-d
同時(shí)更改訪問(wèn)和修改時(shí)間瘾英。顯示符號(hào)鏈接指向的路徑:
readlink
枣接。統(tǒng)計(jì)文件信息:
!/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ù)個(gè)數(shù)缺谴,$0
是腳本自己的名字但惶,$1
是傳給腳本的第一個(gè)參數(shù),file -b
只打印文件類型湿蛔,cut -d , -f 1
選取以逗號(hào)分隔的第一列數(shù)據(jù)膀曾,<(find $path -type f -print)
獲取子進(jìn)程輸出數(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
將對(duì)掛載設(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
。
開(kāi)關(guān)光驅(qū)托盤:eject
和eject -t
栗弟。生成修補(bǔ)文件:
diff -u version1.txt version2.txt > version.patch
污筷。
修補(bǔ):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
。
隨進(jìn)程結(jié)束而結(jié)束關(guān)注:tail -f file --pid $PID
诈皿。列出當(dāng)前目錄下的目錄:
ls -d */
林束,ls -F | grep /$
,ls -ls | grep ^d
稽亏,find . -type d -maxdepth 1 -print
壶冒。命令行中的目錄切換:
pushd
,在棧中壓入目錄并切換截歉;dirs
顯示棧中的目錄胖腾;pushd +num
,切換到棧中的第num
個(gè)目錄瘪松,從0開(kāi)始咸作;popd
刪除當(dāng)前目錄并進(jìn)入切換前的目錄;popd +num
刪除指定目錄凉逛。統(tǒng)計(jì)行數(shù)性宏、單詞數(shù)、字符數(shù):
wc
状飞,分別統(tǒng)計(jì)wc -l/w/c
毫胜。打印文件中最長(zhǎng)一行的長(zhǎng)度wc -L
。以樹(shù)狀結(jié)構(gòu)打印文件和目錄:
tree PATH
诬辈。重點(diǎn)標(biāo)記符合某樣式的文件tree PATH -P PATTERN
酵使。重點(diǎn)標(biāo)記除某樣式外的文件tree PATH -I PATTERN
。同時(shí)打印文件和目錄的大小tree -h PATH
焙糟。以 HTML 形式輸出目錄樹(shù)tree PATH -H http://localhost -o out.html
口渔。
第4章 讓文本飛
正則表達(dá)式的基本組成部分:
^
行首標(biāo)記,$
行尾標(biāo)記穿撮,.
匹配任意一個(gè)字符缺脉,[]
匹配包含在方括號(hào)內(nèi)的任意一個(gè)字符,[^]
匹配除方括號(hào)內(nèi)的任意一個(gè)字符悦穿,[-]
匹配指定范圍內(nèi)的任意一個(gè)字符攻礼,?
匹配之前的項(xiàng)1次或0次,+
匹配之前的項(xiàng)至少1次栗柒,*
匹配之前的項(xiàng)至少0次礁扮,()
創(chuàng)建用于匹配的子串,{n}
匹配之前的項(xiàng) n 次,{n,}
匹配之前的項(xiàng)至少 n 次太伊,{n,m}
匹配之前的項(xiàng)最少 n 次雇锡、最多 m 次,|
匹配兩邊的任意一項(xiàng)僚焦,\
將前述特殊字符轉(zhuǎn)義锰提。著重標(biāo)記匹配的字符串:
grep string filename --color=auto
。
使用擴(kuò)展正則表達(dá)式:grep -E
或egrep
叠赐。
只輸出匹配的文本:egrep -o
欲账。
打印匹配行之外的所有行:grep -v
屡江。
統(tǒng)計(jì)匹配行數(shù):grep -c
芭概。同一行內(nèi)有多處匹配時(shí),僅算一次惩嘉。統(tǒng)計(jì)匹配的次數(shù)可結(jié)合egrep -o
和wc -l
罢洲。
打印匹配行的行號(hào):grep -n
。
打印字符串的字符偏移:grep -bo
文黎。從整個(gè)文本的第一字符算起惹苗,起始值為0。
打印包含匹配字符串的文件:grep -l
耸峭,不包含的文件grep -L
桩蓉。
遞歸搜索:grep -R
。
忽略大小寫:grep -i
劳闹。
多字符串匹配:grep -e string1 -e string2
院究。將每個(gè)字符串寫入文件的每一行,根據(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
。若有多行匹配窿冯,以--
分隔骗奖。按列打印:
cut -f num file
,多列num1,num2,num3...
执桌。
排除不含定界符的行:-s
鄙皇。
打印除某列外的所有行:cut -f num --complement file
。
指定定界符:-d
仰挣。
按字符或字節(jié)選劝橐荨:-c
或-b
,提取多字段時(shí)必須指定輸出定界符cut -c 0-2,4-6 --output-delimiter " "
膘壶。打印替換后的文本:
sed 's/text/replace/' file
错蝴。定界符/
可任意更換,如,
颓芭,|
顷锰,:
等等。
替換并保存:-i
亡问,此時(shí)不打庸僮稀;同時(shí)保留副本-i.bak
州藕。
全行替換:sed 's/text/replace/g' file
束世。
全行第 n 處開(kāi)始替換:sed 's/text/replace/ng' file
。
移除空白行:sed '/^$/d' file
床玻。
替換所有的三位數(shù):sed 's/\b[0-9]\{3\}\b/NUMBER/g' file
毁涉。\b
表示字符串邊界。
所有單詞放入中括號(hào)內(nèi):sed 's/\w\+/[&]/g
锈死。\w\+
匹配每一個(gè)單詞贫堰,&
對(duì)應(yīng)匹配字符串。
大小寫子串互換位置:sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
馅精。
多個(gè)替換:sed 's/a/A/' | sed 's/c/C/'
或sed 's/a/A/; s/c/C/'
或sed -e 's/a/A/' -e 's/c/C/'
严嗜。
使用變量需要雙引號(hào):sed "s/$text/replace/"
。awk
基本結(jié)構(gòu):awk 'BEGIN{ commands } pattern { commands } END{ commands }' file
洲敢。首先執(zhí)行BEGIN
語(yǔ)句塊漫玄;之后如果滿足pattern
的條件則執(zhí)行其后的語(yǔ)句塊,如未提供pattern
則默認(rèn)執(zhí)行压彭,循環(huán)執(zhí)行直到輸入流讀取完畢睦优;最后執(zhí)行END
語(yǔ)句塊。
NR
:當(dāng)前行號(hào)壮不。
NF
:當(dāng)前行的字段數(shù)汗盘。
$0
:當(dāng)前行的文本內(nèi)容。
傳遞外部變量:awk -v VARIABLE=$VAR
询一,或awk '{ commands }' VARIABLE=$VAR
隐孽。
在BEGIN
語(yǔ)句塊中讀取輸入流可以使用getline
癌椿。
pattern
過(guò)濾:NR < 5
行號(hào)小于5的行,NR==1, NR==5
行號(hào)在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)計(jì)詞頻:
#!/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
指定定界符。按行逆序打硬槠省:
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章 一團(tuán)亂麻菌仁?沒(méi)這回事
下載網(wǎng)頁(yè):
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
。
斷點(diǎn)續(xù)傳:重新下載時(shí)使用wget -c
郊供。
復(fù)制網(wǎng)站:wget --mirror --convert-links URL
峡碉,或wget -r -N -k -l depth URL
。
輸入用戶名和密碼:wget --user username --password pass URL
驮审,手動(dòng)輸入密碼--ask-password
鲫寄。將網(wǎng)頁(yè)內(nèi)容以 ASCII 編碼的形式存儲(chǔ)到文件中:
lynx URL -dump > webpage_as_text.txt
吉执。下載數(shù)據(jù)寫入文件:
curl URL -o filename --progress
。
斷點(diǎn)續(xù)傳:curl -C - URL
地来。
從特定的文件偏移處下載:curl URL/file -C offset
鼠证。
設(shè)置參照頁(yè):curl --referer referer_URL target_URL
。
第6章 B 計(jì)劃
歸檔:
tar -cf output.tar file1 file2 file3 ...
靠抑。
列出歸檔的文件:tar -tf output.tar
量九,或冗長(zhǎng)模式tar -tvf
。
追加文件:tar -rf output.tar new_file
颂碧。
提溶小: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
川队,提取時(shí)會(huì)選最新的。
判斷歸檔文件與本地同名文件是否相同:tar -df output.tar
睬澡。
刪除:tar -f ouput.tar --delete file1 file2
固额。
壓縮:-j
zip2 格式,-z
gzip 格式煞聪,--lzma
lzma 格式斗躏。
根據(jù)擴(kuò)展名自動(dòng)壓縮:-a
。
歸檔時(shí)排除指定文件: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
。
提染渤隆:cpio -id < archive.cpio
燕雁。
cpio
提取至絕對(duì)路徑,tar
提取至相對(duì)路徑窿给。壓縮:
gzip file
贵白。
解壓:gunzip file.gz
。
列出:gzip -l file.gz
崩泡。
指定輸出文件:-c >
禁荒。
最低壓縮比--fast
或-1
,最高壓縮比--best
或-9
角撞。
直接讀惹喊椤:zcat file.gz
勃痴。
另有bzip2
/bunzip2
、lzma
/unlzma
热康。歸檔并壓縮
zip
沛申,提取unzip
不會(huì)刪除源文件。
遞歸-r
姐军,更新-u
铁材,刪除-d
,列出-l
奕锌。利用多核歸檔并壓縮:
tar -c directory_to_compress | pbzip2 -c > output.tar
著觉。
解壓并提取:pbzip2 -dc output.tar | tar -x
惊暴。
指定核數(shù):-p
饼丘。
指定壓縮比:-1
至-9
。超高的壓縮率辽话,且無(wú)須解壓即可讀取少量文件肄鸽,使用 squashfs 只讀文件系統(tǒng)纹冤。
創(chuàng)建:mksquashfs SOURCES compressedfs.squashfs
勿负。
利用環(huán)回方式掛載:mount -o loop compressedfs.squashfs /mnt/squash
澳化。
創(chuàng)建時(shí)排除部分文件:-e
再芋,或根據(jù)文件-ef
,使用通配符-wildcards
保屯。歸檔并壓縮傳輸:
rsync -avz source destination
辽俗。路徑最后有/
和沒(méi)有是不同的。
排除部分文件:--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
担敌;
標(biāo)注檢查點(diǎn)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
表示提取第一個(gè)分區(qū)的內(nèi)容行楞。
第7章 無(wú)網(wǎng)不利
MAC 地址欺騙:
ifconfig eth0 hw ether new_MAC
攒暇。重啟后失效。列出域名的所有 IP 地址:
host google.com
子房。
同時(shí)列出 DNS 資源記錄:nslookup google.com
形用。設(shè)置默認(rèn)網(wǎng)關(guān):
route add default gw IP INTERFACE
。查看途經(jīng)的網(wǎng)關(guān):
traceroute google.com
证杭。找出網(wǎng)絡(luò)上所有的活動(dòng)主機(jī):
#!/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
。
遠(yuǎn)程執(zhí)行躯砰,本地顯示:ssh user@remotehost 'command1; command2; command3'
每币。
壓縮傳輸:-C
。FTP 連接:
sftp user@remotehost
琢歇。上傳put
兰怠,下載get
。
指定端口:-oPort=PortNumber
李茫。scp -p
將保留文件的權(quán)限和模式揭保。SSH 自動(dòng)化認(rèn)證:
創(chuàng)建密鑰,指定加密算法為 RSAssh-keygen -t rsa
魄宏;
上傳至遠(yuǎn)程主機(jī)ssh user@remotehost "cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_rsa.pub
或ssh-copy-id user@remotehost
秸侣。將本地主機(jī)端口8000上的流量轉(zhuǎn)發(fā)到 www.kernel.org 的端口80上:
ssh -L 8000:www.kernel.org:80 user@localhost
。
將遠(yuǎn)程主機(jī)端口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)入后臺(tái),-N
說(shuō)明無(wú)需執(zhí)行命令予跌。
反向端口轉(zhuǎn)發(fā):ssh -R 8000:localhost:80 user@REMOTE_MACHINE
搏色。在本地掛載點(diǎn)上掛載遠(yuǎn)程驅(qū)動(dòng)器:
sshfs -o allow_other user@remotehost:remote_path /mnt/mountpoint
。列出開(kāi)放端口及運(yùn)行的服務(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)建無(wú)線熱點(diǎn):
#!/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
運(yùn)行./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ī)則鏈中乞榨。
清除所有改動(dòng):iptables --flush
秽之。
第8章 當(dāng)個(gè)好管家
打印文件或目錄占用的磁盤空間:
du
当娱。
打印目錄中每個(gè)文件占用的空間:-a
。
默認(rèn)以字節(jié)為單位考榨,標(biāo)準(zhǔn)容量單位-h
跨细。
指定字節(jié) / KB / MB / 塊為單位:-b/k/m/B
。
打印總計(jì):-c
河质,只打印總計(jì)-s
冀惭。
排除部分文件:--exclude
,或根據(jù)文件--exclude-from
掀鹅。
指定深度:--max-depth
散休。
排除所有掛載點(diǎn):-x
。
找出大文件:find . -type f -exec du -k {} \; | sort -nrk 1 | head
乐尊。磁盤可用空間:
df -h
戚丸。打印運(yùn)行時(shí)間:
time COMMAND
。
統(tǒng)計(jì)信息寫入文件:/usr/bin/time -o output COMMAND
扔嵌,不覆蓋而是追加至 output-a
限府。
格式化輸出:-f "FORMAT STRING"
。real 時(shí)間%e
痢缎,user 時(shí)間%U
胁勺,sys 時(shí)間$S
。此外還有很多可用參數(shù)独旷。當(dāng)前登錄用戶:
who
署穗,w
,users
嵌洼。查看加電運(yùn)行時(shí)間:
uptime
案疲。上一次啟動(dòng)及登錄信息:
last
,指定記錄日志-f
咱台。
指定用戶:last USER
络拌。
指定會(huì)話:last reboot
。
失敗的用戶登錄會(huì)話信息:lastb
回溺。統(tǒng)計(jì)一小時(shí)內(nèi)占用 CPU 最多的十個(gè)進(jìn)程:
#!/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 使用率混萝,$$
是腳本的進(jìn)程 ID遗遵。
以固定間隔監(jiān)視命令輸出:
watch
。
指定間隔秒數(shù):-n
逸嘀。默認(rèn)為兩秒车要。
突出差異:-d
。監(jiān)視目錄訪問(wè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
僅當(dāng)源日志文件非空時(shí)才對(duì)其進(jìn)行輪替悉患;
size
限制日志文件的大小榆俺;
compress
壓縮舊日志售躁;
weekly
輪替時(shí)間間隔;
rotate
保留的舊日志文件的歸檔數(shù)量茴晋;
create 0600 root root
指定權(quán)限和屬性陪捷。重要的應(yīng)用程序應(yīng)將執(zhí)行過(guò)程記錄在日志文件中。Linux
/var/log
的重要日志文件包括:
boot.log
系統(tǒng)啟動(dòng)信息诺擅;
httpd
Apache Web服務(wù)器日志市袖;
messages
發(fā)布內(nèi)核啟動(dòng)信息;
auth.log
用戶認(rèn)證日志烁涌;
dmesg
系統(tǒng)啟動(dòng)信息苍碟;
mail.log
郵件服務(wù)器日志;
Xorg.0.log
X 服務(wù)器日志烹玉。向
/var/log/messages
中寫入日志信息:logger MESSAGE
驰怎。特定標(biāo)記-t
。寫入另一日志文件的最后一行-f
二打。檢測(cè)入侵:
#!/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)視遠(yuǎ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
電源使用的測(cè)量與優(yōu)化:
powertop
。生成 HTML 格式的報(bào)表--html
继效。I/O 監(jiān)視:
iotop
症杏。只顯示正在進(jìn)行-o
,非交互式打印兩次-b -n 2
瑞信,特定進(jìn)程-p `pidof command`
厉颤。檢查磁盤:
fsck
。檢查所有/etc/fstab
中的-A
凡简。自動(dòng)修復(fù)-a
逼友。模擬操作-AN
。
第9章 管理重任
列出占用 CPU 最多的10個(gè)進(jìn)程:
ps -eo comm,pcpu --sort -pcpu | head
秤涩。
指定有效用戶:-u
帜乞。
指定真實(shí)用戶:-U
。
指定 TTY:-t
筐眷。
輸出線程相關(guān)信息:-L
黎烈。
列出依賴的環(huán)境變量:ps -eo cmd e
。列出進(jìn)程的所有 PID :
pgrep command
。
指定定界符:-d
照棋。
指定用戶:-u
资溃。列出所有可用的進(jìn)程信號(hào):
kill -l
。
發(fā)送指定信號(hào):kill -s SIGNAL PID
烈炭。
常用信號(hào):SIGHUP 1溶锭,SIGINT 2,SIGKILL 9梳庆,SIGTERM 15暖途,SIGTSTP 20。
通過(guò)命令名:killall
膏执。
捕捉并響應(yīng)信號(hào):trap 'signal_handler_function_name' SIGNAL_LIST
驻售。