交互式和非交互式的shells和腳本
交互式的shell在 tty終端從用戶的輸入中讀取命令. 另一方面, shell能在啓動時讀取啓動文件,顯示一個提示符並默認激活作業控制. 用戶能交互地使用shell.
運行腳本的shell一般都是非交互的shell. 但腳本仍然可以存取它擁有的終端. 腳本里甚至可以仿效成可交互的shell.
1 #!/bin/bash 2 MY_PROMPT='$ ' 3 while : 4 do 5 echo -n "$MY_PROMPT" 6 read line 7 eval "$line" 8 done 9 10 exit 0 11 12 # 這個例子腳本, 和上面的解釋由 13 # Stéphane Chazelas 提供(再次感謝). |
讓我們考慮一個要求用戶交互式輸入的腳本,通常用read語句 (參考例子 11-3). 真正的情況可能有些混亂.以現在假設的情況來說,交互式腳本被限制在一個tty設備上,它本身已經是從一個控制終端或一箇中被用戶調用的.
初始化和啓動腳本不必是非交互式的,因爲它們必須不需要人爲地干預地運行。許多管理和系統維護腳本也同樣是非交互式的。不多變的重複性的任務可以自動地由非交互式腳本完成.
非交互式的腳本可以在後臺運行,但交互腳本在後臺運行則會被掛起,等待永遠不會到達的輸入。解決這個難點的辦法可以寫預料這種情況的腳本或是內嵌here document 的腳本來獲取腳本期望的輸入,這樣就可作爲後臺任務運行了.在最簡單的情況,重定向一個文件給一個read語句提供輸入(read variable <file). 這就可能適應交互和非交互的工作環境下都能達成腳本運行的目的.
如果腳本需要測試當前是否運行在交互shell中,一個簡單的辦法是找一下是否有提示符變量,即$PS1是否設置了. (如果腳本需要用戶輸入數據,則腳本會顯示一個提示符.)
1 if [ -z $PS1 ] # 沒有提示符? 2 then 3 # 非交互式 4 ... 5 else 6 # 交互式 7 ... 8 fi |
1 case $- in 2 *i*) # 交互式 shell 3 ;; 4 *) # 非交互式 shell 5 ;; 6 # (Courtesy of "UNIX F.A.Q.," 1993) |
腳本可以使用-i選項強制在交互式模式下運行或腳本頭用#!/bin/bash -i. 注意這樣可能會引起腳本古怪的行爲或當沒有錯誤出現時也會顯示錯誤信息.