這是本文件的舊版!
可用 set 指令查看現有的環境變數
環境變數 | 說明 |
---|---|
HOME | 家目錄 |
郵件儲存位置 | |
PS1 | 第一個提示符號,等待使用者命令 |
PS2 | 第二個提示符號,收到的指令不完整,等待使用者繼續輸入 |
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ PS2='> '
控制字 | 功能 |
---|---|
\a | 一嗶聲 |
\e | 跳脫字元 |
\H | 主機名稱(較長格式) |
\h | |
\n | 換行 |
\s | Shell Name |
\T | 以 12 小時制顯示時間 |
\t | |
\@ | |
\u | 使用者名稱 |
\W | 完整工作目錄 |
\w | 目前目錄 |
\$ | root 會顯示「#」,一般使用者則為「$」 |
| 印出反斜線 |
在 ~/.bashrc 加上
bind '"\x1b\x5b\x41":history-search-backward' bind '"\x1b\x5b\x42":history-search-forward'
參考 zxvc.bbs@ptt.cc 寫的
如果想知道bash有多少好用的hotkey, 只要man bash,然後搜尋『history-search-backward』, 就可以在history-search-backward附近找到一堆hotkey。 或者在bash中輸入 $ bind -p 也可以看到很多hotkey,只不過沒有詳細說明。 另外『\M-』這個prefix在一般PC鍵盤上代表的是ESC key, 這man bash也是可以查得到。 如果想知道某個按鍵的keymap(例如Up鍵),可以在『純終端機』 (我不清楚為什麼虛擬終端機會不能用showkey)輸入 $ showkey -m 查到,但是這是10進位的值,要把它轉成16進位再加上『\x』 才可以跟某個function bind在一起。 例如:Up鍵與history-search-backward bind在一起: $ bind ‘”\x1b\x5b\x41″:history-search-backward’
直接指定變數的值,使用時前面加 $
vari = 5 echo "var = $vari"
$ ./script.sh ~/temp.txt temp2.txt
此時,在程式中
$0 = ./script.sh $1 = ~/temp.txt $2 = temp2.txt $* = ~/temp.txt temp2.txt // 所有參數 $# = 2 // 參數個數
將原本的參數換成新指令的輸出
set `date` echo "$4 $5 $1 $3 $2 $6"
read input echo $input
a=1 b=2 c=`expr $a + $b` # 等號前後不可以有空白 echo $c
若為 true 則傳回 1,false 為零
test a -eq b
^ 符號 ^意義^
-eq | = |
-ne | != |
-lt | < |
-le | < = |
-gt | > |
-ge | >= |
符號 | 意義 |
---|---|
= | str1 = str2 |
!= | str1 != str2 |
-n | 不是空字串 |
-z | 空字串 |
選項 | 意義 |
---|---|
-l | 是否為連結檔案 |
-d | 目錄 |
-e | 存在 |
-f | 存在且為一般檔案 |
-r | 存在且可讀 |
-w | 存在且可寫 |
-x | 存在且可執行 |
-nt | 比較兩檔案修改時間,如: file1 -nt file2 |
if 條件判斷 then ... fi
關鍵字要自成一行,若硬要同行,要用分號分隔,但 then 後面不用分號
if 條件 ; then ... ; fi
if test -f $1 ; then echo "$1 is a reqular file." ; fi
if [ $1 -eq $2 ] ; then echo "equal" ; else echo "not equal" ; fi
if [ ! -e $1 ] ; then ... ; fi # 如果 $1 的檔案不存在
以下兩行相同
if [ -r $1 ] && [ -x $1 ] if (test -r $1) && (test -x $1)
if 條件 then ... else ... fi
if 條件 then ... elif then ... else ... fi
每一 pattern 用兩個分號分隔,每一敘述用一個分號。
case variable in pattern_1) [statement] ;; pattern_2) [statement1]; [statement2];; ... esac
case $1 in 1) echo "One";; 2) echo "Two"; echo "2";; esac
pattern 可使用正規表示式:
case $1 in *a) echo "End with a";; *b) echo "b";; esac
List 中所有的元素接執行一次
for var in List do ........ done
for file in `ls` do if [ -f $var ] ; then echo "$file is a reqular file."; done
while 條件 do ...... done
和 while 相反,在條件不成立時執行。
until 條件 do ...... done
系統將 List 中的所有元素當作選項,並以環境變數 PS3 作為 Prompt,提示使用者輸入,當使用者輸入某個選項時執行 do done 間的程式。
select var in List do ...... done
#!/bin/bash PS3="INPUT: " select var in `ls` do if [ $var ]; then if [ -f $var ];then echo "$var reqular." else echo "$var no reqular." fi else echo "Bad input" fi done
可在後面接數字,代表要跳出哪個迴圈,如:break2 指要中斷第二個迴圈。
函數宣告必須在呼叫之前完成,因為 Shell script 是直譯程式,且需注意:1. 全域和區域變數的範圍;2. 傳參數的用法。
Function name { ...... }
或
function_name() { ...... }
有三種不同性質的變數。
由系統產生,必定是全域變數。
由函式被呼叫時所附加的參數而定,因此必為區域變數,在不同的函式用同樣的方法使用,但數值不同。
$1, $2, $3, ...
除非特別指定成 local,不然皆為全域變數。
local var1="string"
#!/bin/bash funct () { echo "Inside -- funct: $# args: $1 $2 $3" } echo "Outside -- $0: $# args: $1 $2 $3" funct input1 input2 input3 // 呼叫函式
$ ./test.sh in1 in2 in3 Outside -- ./test.sh: 3 args: in1 in2 in3 Inside -- funct: 3 args: input1 input2 input3
定期分析 apache 的 error log 中,找不到檔案的部份,郵寄給管理者參考。
#! /bin/bash ( for x in `grep "File does not exist:" /var/log/apache2/error.log | awk '{print $13}' | sort | uniq`; do grep $x /var/log/apache2/error.log | wc -l | tr -d '\n'; echo " : $x"; done | sort -rn | head -20 ) | mail -s "Missing file report" webmaster@domain.name
並在 crontab 中加入(需 root 權限)
0 21 * * 5 /root/apache_file_no_found_error.sh