shell使用攻略

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>
    • 轉義 ' " $ `` \
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 selectphp


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}shhtml

  • 字符串比較,= != ;數字比較 -eq -ne -lt -le -gt -gepython

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/cVAR=/tmp/*,求如下命令的輸出:linux

  1. ls '$VAR'
  2. ls "$VAR"
  3. ls $VAR
  4. ls $VARa
  5. ls ${VAR}a
  6. eval ls "$VAR"

已知:/etc/hosts的內容爲下:git

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?shell


列出你最經常使用到的linux命令編程

grep awk sed find vi git  
cd ls echo cat cp mv wl tar

參考

相關文章
相關標籤/搜索