文章出處
文章列表
shell 是什么
~ $ ls /bin/*sh
/bin/bash /bin/csh /bin/ksh /bin/sh /bin/tcsh /bin/zsh
是什么
- kernel shell
- 命令解釋器,和 kernel 交互
- 命令語言、程序設計語言
特性
- 命令集
- 膠水語言
- 操作系統外殼接口
適合場景
- 自動化簡單任務
- 快速、簡單完成原型
劣勢
- 移植性 grep --version wget--version
- 執行效率
- 組織性,結構性
- 不支持面向對象特性
shell 特性
wget uc.cn -O uc.html 2>/dev/null || echo "Failed to get url"
- 面向字符串
- 元字符(metacharacter,分割字符串)
space tab | < > & ( ) ;
- 控制字符(control operator,分割命令)
|| & && ; ;; ( ) | |& <newline>
- 轉義
' "
$ `` \
- 元字符(metacharacter,分割字符串)
var=3+5
echo '$$ `uname` $var $((var))'
echo "$$ \$ `uname` $var $((var))"
- 字符串展開
- 利用元字符分割字符串
- 如果字符串是用來給變量賦值,則不管它是否被雙引號包圍,都認為它被雙引號包圍
- 大括號展開{};波浪線展開~、~-/、~+/ (不被單引號和雙引號包圍)
- 參數和變量展開$USER $var $1 $@ $# ${var[i]} ${var:?value} ${var##value} ${var/pat/str};命令替換 ${cmd} `cmd`;算數展開 $((a+b)) (不被單引號包圍)
- 單詞分割;路徑展開 (不被單引號和雙引號包圍)
- 去掉字符串外面的引號 (如需重復以上流程使用 eval 聲明)
echo {a,b}cd{e,f} ~ ~-/ `uname` $(ls /bin/[kcz]sh) $$ `ls /bin/e*` /bin/?sh ${var} $(($var)) $#
- 字符串使用
- 命令
- 外部命令,命令名、選項、參數
ls -l /home
- 內部命令,
break continue : . echo eval exec exit export expr printf return set shift trap unset
- 外部命令,命令名、選項、參數
- 表達式
((3+5))、[[ 4 > 5]]
- 賦值
var=value
- 命令
- 常見語法
- 簡單命令
cd ~
- 管道
uname |grep linux
- 命令序列
; & || &&
- 復合命令
() {} (()) [[]]
- 簡單命令
- 流程控制選擇
if condition1; then
statements
elif condition2; then
statements
else
statements
fi
- 流程控制-循環
for var in one two three four five; do
echo '$var is '$var
done
while
until
case
select
shell 實戰
- 對文件進行按行處理
cat in.txt |while read url; do
echo "got $url"
done > out.txt
- 生成配置包
tar -zcvf update.`date '+%Y%m%d_%H%M%S'`.tar.gz somedir
- 生成模板文件(其他格式化文本)
cat <<EO > index.html
<html>
<head>
<title></title>
</head>
hello $USER
your computer's name `hostname`
</html>
EO
- 日志監控及定時處理
/usr/bin/find /home/dir -type f ! \( -name "*.bz2" -o -name "*.gz" \) -mmin +120 -exec bzip2 {} \; >/dev/null 2>&1
- 去除文件重復(保留文件原有順序)
awk '!a[$0]++' in.txt > out.txt
- 從文件中提取指定的內容
grep -Phio "(?<=\`uri=)[^\`]+" *.log |sort |uniq
grep -Pio "(?<='customizable': ')[^',]+" *.log
`uri=http://13aaaa.com/html/PIC01/332190.html`wait=0.09`slow...
- 文件非交互式編輯
sed -i 's/dispatch_rule/dispatch_rule = /g' in.txt
- 計算
awk -F, '{sum+=$2} END{print sum}
- 條件運算 && 、 ||
ps -ef |grep start_all.py |grep -v grep && exit 2 || python start_all.py
- 變量替換、去除首尾字符
url='http://www_sina_com_cn/path/index.html'
echo ${url//_/.}
echo ${url#http://}
echo ${url%%/*}
- 循環
for i in $(seq -w 0 23); do
echo "log.8???_2014-10-15_$i"
done
- 查找
find . -type f |xargs -n 1000 grep -Pio -m 1 $key
find /nfs -size +10000k –xdev –exec ls –lh {} \;
find ~ -mtime +7 -name "*.log*" -exec rm -rf {} \;
- 文件權限控制
r4 w2 x1
u(ser) g(roup) o(ther) a(ll)
chmod o+r filename
chmod 775 filename
chown user:user_group filename
shell的坑
- 命令的返回狀態 0表示正常
if uname |grep -i linux; then
echo 'you are using linux'
fi
通配符擴展(和正則區別)
*
?
[set]
[^set]
{ba,c,k,z,tc}sh
字符串比較,
=
!=
;數字比較-eq -ne -lt -le -gt -ge
if [ "$t1" != "$t2" -a $n1 -eq $n2 ] || [ $n3 -eq 100 ]; then
...
fi
- crontab 任務列表不讀環境變量,執行腳本要絕對路徑
30 * * * * source /home/nemo/.bashrc; /home/nemo/somescript > /dev/null
0-59 1-23 1-31 1-12 0-6 somescript
- 重定向前后不可為同一文件
sort in.txt > in.txt
最佳實踐
- 函數內部變量使用 local 聲明
func () {
local var=hello;
}
- 變量用花括號
echo echo ${BASH}_VERSION
echo ${10}
- 字符串變量用雙引號
[ "$day" = yes ]
- 一步到位
mkdir -p some/conf/{first,second/{third,forth}}
vi some/domains.conf
find . -name "dom*.conf" -exec vi {} \;
- 其他
tar xvf -C ~ /nfs/some.tar.gz # 減少移動文檔
cd ~ && tar xvf -C ~ /nfs/some.tar.gz # 鼓勵使用列表
使用 \ 進行長命令折行;
() {} 對命令分組執行
rm *.xml; rm some -r #避免 rm * -rf
附:
shell 內部特殊參數
字符 | 通用含義 | 示例及說明 |
---|---|---|
* | 位置變量列表,使用IFS第一個字符分開 | fun 'hello world' |
@ | 位置變量列表 | |
# | 位置參數數目 | |
? | 最近一個前臺任務的返回狀態 | $? |
- | 所有發送給shell的標志 | |
$ | 進程ID | |
! | 最近被放到后臺執行的命令的進程ID | |
_ | 前一個命令最后一個參數 | |
0 | shell、腳本名、函數名 | |
1-9 | shell、腳本、函數的位置參數 | $2 ${10} |
練習
已知
ls /tmp/*
=/tmp/a /tmp/b /tmp/c
,VAR=/tmp/*
,求以下命令的輸出:
ls '$VAR'
ls "$VAR"
ls $VAR
ls $VARa
ls ${VAR}a
eval ls "$VAR"
已知:/etc/hosts的內容為下:
192.168.1.11 oldboy11.etiantian.org
192.168.1.21 oldboy21.etiantian.org
192.168.1.31 oldboy31.etiantian.org
#192.168.1.111 oldboy111.etiantian.org
怎么才能在輸入IP后找到/etc/hosts里對應的唯一的hostname?
列出你最常用到的linux命令
grep awk sed find vi git
cd ls echo cat cp mv wl tar
參考
文章列表
全站熱搜