Shell Script
記錄一些 Unix/Linux 常用的 shell and script 概念.
login and non-login shell
登入 shell 分兩種狀態,分別是 login shell
和 non-login shell
.
login shell
: 需要打 id/pwd 的
- login shell 會依序讀取:
/etc/profile
~/.bash_profile
~/.bash_login
~/.profile
- 後面三個是使用者的設定, 只要找到其中一個, 其他的就不會讀.
non-login shell
: 已經在 X-Window 裡了, 不需要登入動作, 或者像是執行 cron job.
- 依序讀取:
/etc/bashrc
->~/.bashrc
source /etc/profile
: 用來重新載入這些設定, 而不需要重新開 shell, 像是跑 cron job, 需要用到完整的訊息, 我就會這樣寫, 以下是每天自動開關 AWS Instance 的例子:
1 | # Boot/Shutdown AWS Instance |
使用 crontab 的注意事項
ubuntu 裡,可以直接在 crontab 裡直接附加環境變數,像是:
1 | APP_HOME=/usr/local/bin/app1 |
這樣 script.sh 就可以直接使用。
但是在 centos 裡的無法這樣使用,所以一般會把環境變數在 script 裡宣告。
crontab 的 debug 最常遇到的問題就是手動跑 script 沒問題,進入 crontab 跑問題就一堆,而且通常都不知道原因在哪。
debug 的方法很簡單,寫一個 script 如下:
1 |
|
確認這裡的東西是正常的,如預期的。問題通常都在這裡。
stdin / stdout / stderr
- stdin: 代碼
0
或者用<
or<<
- stdout: 代碼
1
, 或者用>
or>>
- stderr: 代碼
2
, 或者用2>
or2>>
- 只顯示 stdout, 將 stderr 的訊息丟掉:
commd 2> /dev/null
- 只顯示 stdout, 將 stderr 的訊息丟掉:
- 將 stdout / stderr 資料都寫入同一個檔案, 兩種寫法:
cmd > log 2>&1
, ex:find /Users/ -name > /tmp/log 2>&1
cmd &> log
, ex:find /Users/ -name &> /tmp/log
Environment Variables
一些隱含的環境變數,經常在 shell script 使用, 打 set
or env
可以看到一堆. env
: 只會列出環境變數, set
除了環境變數, function 也會列出來.
$$
: 顯示目前的 PID (Process ID)cd -
: 上一個執行的路徑, 等於cd $OLDPWD
cd ~
: 表示cd $HOME
return code
$?
: 上一個 command 的 return code,rc = 0
: 沒有 exception or errorrc > 0
: 執行結果問題, 參考man command
的說明
Return code 可以搭配 &&
, ||
使用, 也就是連續執行 command 後, 會依據 rc 結果判斷是否繼續執行.
cmd1 && cmd2
: cmd1 結果 (rc) 為 0, 才繼續執行 cmd2cmd1 || cmd2
: cmd1 結果為 0, cmd2 不會繼續執行cmd1; cmd2
: 依序執行 cmd, 不管結果如何
history
unix base 大多支援 cli 的 history, 善用它可以解省很多敲字,增加工作效率。
history
: 顯示歷史指令, 每個指令前面都會有序號,可以透過!{N}
直接執行control + r
: 用關鍵字搜尋歷史- 可以設定 history 顯示的格式,在
~/.bashrc
加入以下,就會顯示日期和時間
1 | # format of history |
參考資料
Updated
- 2017/05/27: Add history, crontab