linux shell 學習摘記(1)

onephone發表於2016-09-28

《linux shell 指令碼程式設計攻略 (第2版)》 第一章 “小試牛刀” 筆記

主要命令:let, cat, 變數字串處理, 數學計算, 管道|, 重定向, $, expr, bc, echo, $#, $*, $0, eval, tr, printf, read, tput, 迴圈語句, 條件語句, 分隔符IFS

  • 文字行#!/bin/bash中的#!讀作 shebang (也可讀做 hashbangpound-bang參考維基

  • 終端列印除了echo命令還可以用printf(語法規則同C語言類似),如printf "%s %f\n" swf 1234輸出 swf 1234.000000

  • 變數替換在單引號中無效

  • 列印彩色字型echo -e "\e[1;31m This is red text \e[0m"\e[1;31m將顏色設為紅色(;前的數字表示背景顏色,;後的表示字型顏色),\e[0m將顏色重新置回

  • 查詢某程式執行時環境變數cat /proc/程式ID/environca (pgrep gedit檢視程式gedit的PID,或使用ps aux | grep gedit檢視)

  • tr將輸出重新格式化 cat /proc/84354/environ | tr '\0' '\n'

  • 獲取字串長度var=wenfeng; echo ${#var}(助記:#是number sign),獲取當前使用的SHELL echo $0echo $SHELL

  • ${parameter:+expression} 如果parameter有值且不為空,則使用expression的值。prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1; } (eval`可將多個引數整合成一個引數)

  • 顯示/修改Bash提示字串echo $PS1/PS1="wefeng"

  • shell數學運算

    1. let 變數名前不需要用$,如let result=no1+no2; echo $result
    2. (())result=$(( no1 + 50 ))result=$ (( $no1 + 50 ))
    3. []result=$[ no1 + no2]result=$[ $no1 + 5 ]
    4. exprresult=反引號expr 3 + 4反引號result=$(expr $no1 + 5)
    5. bc命令(支援浮點數echo "scale=2;3/8" | bc 設定小數位數為2; echo "obase=2;$no" | bc將數字轉化為2進位制; echo "obase=10;ibase=2;$no" | bc 將二進位制轉化為十進位制
  • 重定向

    1. stderr轉換成stdout重定向 cmd 2>&1 stdout.txt 或者 cmd &> output.txt
    2. command | tee FILE1 FILE2 接收來自stdin的資料,將副本寫入FILE1和FILE2,同時也將副本左後後續命令的stdin
    3. cmd - 將stdin作為命令引數
  • 指令碼內部檔案塊重定向此處有程式碼

  • 自定義檔案描述符 exec 3<input.txt exec 5>>output.txt此處有程式碼

  • 陣列array_var=(s w f), echo ${array_var[0]}列印一個元素, echo ${#array_var[*]}列印陣列長度,echo ${!array_var[*]}列印出陣列索引列表,echo ${array_var[*]} 列印出所有元素

  • 關聯陣列(相當於字典)先宣告declare -A ass_array,再賦值ass_array=([index1]=val1 [index2]=val2) 或者 ass_array[index3]=val3 其他操作同上,只是索引不再是數字了

  • 當用alias設定了別名命令後,當不想用這個別名是,可對其進行轉義即 \command

  • 獲取當前終端行數/列數/終端名 tput lines/tput cols/tput longname; tput sc儲存游標位置, tput rc恢復游標位置 tput ed清除從當前游標位置到行尾之間的所有內容 (下面實現一個計時器)此處有程式碼

  • 通過stty實現 輸入密碼時不應顯示輸入內容(也可直接read -s啟動slient模式,但stty更通用)此處有程式碼

  • date +%s 列印timestamp (從1970年1月1日0點開始的秒數)即POSIX時間; date "+%d %B %Y" 按格式輸出

  • 除錯指令碼此處有程式碼

    1. bash -x script.shsh -x script.sh
    2. set -xset +x(執行命令後會顯示該指令及其引數);set -v當命令進行讀取時顯示輸入,set +v進位制列印輸入 詳細介紹
    3. 將shebang從#!/bin/bash 改成 #!/bin/bash -xv 也可(./script.sh執行)
    4. 自定義格式顯示除錯資訊,新建如下指令碼,然後命令列鍵入 [root@share codes]# _DEBUG=on sh debug.sh (:告訴shell不進行任何操作)
  • 函式和引數

    1. $@ 被擴充套件成 $1 $2 $3
    2. $* 被擴充套件成$1c$2c$3(c是IFS的第一個字元, IFS即internal field seprator, env | grep IFSset | grep IFS檢視)
    3. $? 獲取命令或函式的返回值
    4. "$@" 比 "$*" 更常用,後者會把所有引數當作單個字串處理
    5. 遞迴 F() { echo $1; F hello; sleep 1; },這是 fork bomb :(){ :|:& };: (可通過修改/etc/security/limits.conf或命令ulimit來限制生成的最大程式數)維基擴充套件
    6. 匯出函式 export -f fname 可將函式的作用域擴充套件到子程式中
    7. 向命令傳遞引數的方式command -p -v -k 1 file或者command -pv -k1 file或者command -pvk 1 file或者command file -pvk 1
  • 儲存命令的輸出此處有程式碼

    1. $( ) 通過子shell方式, 如 output=$(ls | cat -n) 子shell裡面的變化如cd XX等不會反應到主shell中
    2. 反引用方式(通過反引號)
    3. 可將子shell或反引用放入以個雙引號中,以保留空格和換行符(\n)
  • read -n 5 -s -t 2 -d ":" -p "Enter your password:" var 從輸入中以無回顯的方式讀取5個字元並存入變數var中,且需要在2秒內輸入,以:作為輸入行的結束符,終端會有"Enter your password:"的提示

  • true作為/bin中的一個二進位制檔案來實現的,即表示每執行一次便會生成一個程式,若不想則可以通過內建的:命令(其總會返回0)此處有程式碼

  • 欄位分隔符 IFS 此處有程式碼

  • 迴圈語句 for in do done, while do done, until do done 連寫成一行時,do前要用;

  • 比較語句 if then fi, if then else if then else fi 連寫成一行時,then前用;

    1. [ condition ] && action[ condition ] || action
    2. 算數比較 -eq, -ne, -lt, -ge, -le; [ $var1 -ne 0 -a $var2 -gt 2 ](AND條件用-a,OR條件用-o),也可分開用類似[ ] && [ ]
    3. 檔案系統相關測試 -f, -d, -e, -b, -w, -r, -x, -L (用[ ])
    4. 字串比較 [[ ]] (-z, -n , ==, !=)

相關文章