歡迎您光臨本站 註冊首頁

tcsh shell 變數

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
tcsh 是最流行的 UNIX® shell 之一。學習如何用 tcsh shell 變數簡化自己的工作以及如何利用 tcsh 的高級安全特性。

tcsh 是原來的 Berkeley UNIX C shell 的改進版本,它是最流行的 UNIX shell 之一。本文討論 tcsh 提供的一些功能:它提供的 shell 變數可以減少幾個常規任務花費的時間,還提供了一些高級的安全特性,比如監視用戶及其命令歷史。本文描述的所有命令和腳本都用 tcsh 6.15 測試過(參見 參考資料)。

如何設置 shell 變數

tcsh 提供幾個內置的 shell 變數。其中一部分(比如 rmstar 和 noclobber)是布爾值,所以建議用 set <variablename> 打開它們。對於 prompt 等其他內置變數,需要使用 set <variablename>=<value> 提供一個值。使用 unset <variablename> 取消變數。清單 1 給出一些基本示例。


清單 1. 如何設置/取消 shell 內置變數
tcsh# set prompt="arpan@tintin# "  arpan@tintin# set autologout=1  arpan@tintin# unset prompt   echo $autologout  1   <prompt has disappeared due to unset operation>  

下面幾節討論 tcsh 通過 shell 內置變數提供的一些最有用的特性。

用 rmstar 預防災難

在 UNIX 中,造成混亂的最常見原因可能是意外地執行了 rm *。大多數用戶在使用 rm 命令時不使用 -i 選項,因此會立即刪除文件。tcsh 定義了一個 shell 變數 rmstar;如果打開這個變數,在用戶執行操作時會顯示提示,要求用戶確認操作。但是,如果用戶在命令提示下運行 rm –f *,就不會出現確認提示。清單 2 演示 rmstar 的用法。


清單 2. 使用 rmstar shell 變數
arpan@tintin# pwd  /home/arpan/scratchpad  arpan@tintin# ls  file1 file2  arpan@tintin# set rmstar  arpan@tintin# rm *  Do you really want to delete all files? [n/y] n  arpan@tintin# ls  file1 file2  arpan@tintin# unset rmstar  arpan@tintin# rm *   arpan@tintin# ls  arpan@tintin#   

防止意外覆蓋現有的文件

造成混亂的另一個典型場景是意外地覆蓋現有的文件。為了防止發生這種情況,應該一直打開 shell 變數 noclobber。(這個變數在 csh shell 中也可用)。注意,這隻能防止把輸出重定向到現有文件;如果使用 cp 或 mv 覆蓋文件,這個變數沒有任何幫助。見清單 3。


清單 3. 使用 noclobber 防止意外覆蓋文件
arpan@tintin# ls   file1 file2  arpan@tintin# set noclobber  arpan@tintin# echo testing > file1  file1: File exists.  arpan@tintin# unset noclobber  arpan@tintin# echo testing > file1  arpan@tintin# cat file1  testing  

還要注意,shell 操作符 >> 和 >! 不考慮 noclobber 的設置。前一個操作符在現有文件中追加內容(所以仍然可以恢複數據),後者覆蓋現有內容。

自動 Tab 補齊

當在 shell 提示上輸入命令時,可以只輸入命令字元串的一部分,然後按 Tab,shell 會自動補齊命令字元串或者給出可用的選擇,這會顯著加快輸入速度。這個功能對於長文件名尤其有意義;可以只輸入前幾個字母並讓 shell 補齊文件名。為了啟用這個特性,需要設置 shell 變數 autolist。清單 4 給出一個示例。


清單 4. 使用 autolist 啟用自動命令補齊
arpan@tintin# ls  this_is_a_big_file test.c threads.h  arpan@tintin# set autolist  arpan@tintin# vi t[TAB]  this_is_a_big_file test.c term.h  arpan@tintin# vi th[TAB]  this_is_a_big_file threads.h  

在這個示例中,[TAB] 表示按 Tab 鍵。在 shell 提示上輸入 vi thi[TAB],shell 會把 thi[TAB] 擴展為 this_is_a_big_file。

使用 addsuffix 在 Tab 補齊期間區分目錄

如果同時設置 addsuffix shell 變數和自動 Tab 補齊,那麼在找到匹配時 tcsh 會在文件夾後面加上一個 / 字元,這樣就更容易區分出文件夾。它在一般文件後面加一個空格。在清單 5 所示的情況中,有一個名為 documents 的文件夾,這個文件夾中有一個名為 deliverables 的文件;用戶輸入 do[TAB],shell 就會顯示 documents/。如果取消 addsuffix 變數,tcsh 就只顯示 documents,這對於判斷 documents 是一般文件還是文件夾很不方便。


清單 5. 在使用 autolist 的同時使用 addsuffix 區分文件夾
arpan@tintin# ls  documents deliverables  arpan@tintin# set autolist  arpan@tintin# ls do[TAB]  arpan@tintin# ls documents  arpan@tintin# set addsuffix  arpan@tintin# ls do[TAB]  arpan@tintin# ls documents/  arpan@tintin# unset autosuffix  arpan@tintin# ls do[TAB]  arpan@tintin# ls documents  

使用 fignore shell 變數避免意外刪除

在某些情況下,限制自動 Tab 補齊特性是有意義的。例如,如果 vi 是一個會話中最常用的命令,那麼把 Tab 補齊提供的命令字元串限制在文本文件範圍內可以節省時間。同樣,如果 .c 和 .cpp 文件還未備份,希望避免意外刪除它們,那麼在 Tab 補齊期間最好不要出現具有 .c/.cpp 擴展名的文件,這樣在 rm 命令後面使用 Tab 補齊特性時就不會刪除它們。為了避免在 Tab 補齊期間顯示 C/C++ 文件,使用 set fignore=(.c .cpp .h)。見清單 6。


清單 6. 使用 fignore 避免在 Tab 補齊期間顯示源代碼文件
arpan@tintin# set autolist  arpan@tintin# ls  memory.h memory.cpp kernel.c memory.o kernel.o  arpan@tintin# rm m[TAB]  memory.h memory.cpp memory.o  arpan@tintin# set fignore=(.c .cpp .h)  arpan@tintin# rm m[TAB]  memory.o  

注意,如果在 rm 後面按 Tab 鍵(而不是在 m 後面按 Tab 鍵),那麼所有 C/C++ 源代碼文件都會出現。

在沒有用戶活動時自動註銷

數據安全是所有組織都很關心的問題。如果意外地讓一個 shell 終端一直打開著,就可能提供訪問重要文件的機會,這種情況隨時都會發生。可以用 tcsh autologout 變數解決這個問題。如果在指定的時間(以分鐘為單位)內沒有用戶活動,用戶就從系統中註銷,返回到 tcsh(如果 tcsh 是登錄 shell)。如果 tcsh 不是登錄 shell,用戶就退出到以前的 shell(這對安全幫助不大)。因此,在安全環境中選擇 tcsh 作為登錄 shell 是有意義的。清單 7 給出一個由於沒有用戶活動導致自動註銷的示例。


清單 7. 由於沒有用戶活動導致自動註銷
arpan@tintin# rsh herge  arpan@herge# set autologout=1  arpan@herge# date  Sat Jun 28 18:13:07 IST 2008    <After 1 min of inactivity>    arpan@herge# auto-logout  Connection to herge closed.   arpan@tintin# date  Sat Jun 28 18:14:10 IST 2008  

改進 tcsh 的安全性:監視正在使用系統的每個用戶

必須一直監視用戶對受保護系統的訪問。tcsh 提供了內置 shell 變數 watch,可以通過它查看正在使用系統的用戶。語法是 set watch=(username1 ttyname1 username2 ttyname2 …)。這會監視用戶 username1 是否在終端 ttyname1 上登錄了。可以用特殊語法 set watch=(any any) 監視所有系統終端上的所有用戶。

在默認情況下,watch 每 10 分鐘檢查一次系統中的登錄/註銷活動。可以通過 watch 語法中的第一個參數指定活動檢查之間的時間間隔,例如:set watch=(5 any any)。見清單 8。


清單 8. 使用 watch 檢查登錄/註銷活動
arpan@tintin# set watch=(5 any any)  <checks for login/logout activity across system every 5 minutes)  arpan@tintin# set watch=(b* any)  <check the login/logout activities of all users whose name starts with b across       any terminal in the network>  

tcsh 還提供內置命令 log,這個命令列出受 watch 變數影響的終端以及正在使用它們的用戶(見清單 9)。注意,如果在沒有設置 watch 的情況下使用 log,就會導致一個錯誤。


清單 9. 使用 log 檢查 watch 所影響的終端的使用情況
arpan@tintin# log  arpan has logged on pts/0 from 132.132.6.73  root has logged on console  zanies has logged pts/5 from 132.132.2.1  

使用 prompt 變數跟蹤當前的工作目錄

tcsh 定義了 prompt 內置 shell 變數,可以通過這個變數定製 shell 提示。最常見的 UNIX 任務之一是跟蹤當前所在的文件夾和機器。不需要一直使用 pwd 和 hostname,只需通過設置 prompt 變數讓 shell 提示反映當前的工作目錄和主機名,即可實現相同的效果。見清單 10。


清單 10. 通過修改 prompt 變數讓 shell 提示反映當前的工作目錄和主機
tcsh-6.15$ pwd  /home/arpan/ibm1  tcsh-6.15$ hostname  tintin  tcsh-6.15$ echo $user  arpan  tcsh-6.15$ set prompt="$user@`hostname`[$cwd] "  arpan@tintin[/home/arpan/ibm1]   

但是,這種方式有一個問題:如果切換到另一個文件夾,提示並不會反映這一變化。為了隨著切換文件夾連續改變提示,應該使用特殊別名 cmdcwd。如果已設置這個別名,那麼在切換到新文件夾之後 tcsh 會執行 cmdcwd 映射到的命令。為了在提示中反映修改後的文件夾,cmdcwd 必須映射到 set prompt 命令(見清單 11)。


清單 11. 使用 cmdcwd 別名在提示中反映修改後的文件夾
tcsh-6.15$ alias cmdcwd 'set prompt="$user@`hostname`[$cwd] " '  tcsh-6.15$ cd   arpan@tintin[/home/arpan/ibm1] cd net  arpan@tintin[/home/arpan/ibm1/net]   

注意,這個方案不但能夠反映 cd 命令所做的文件夾切換,對於 pushd 和 popd 命令也是有效的。如果使用 X-Windows,另一個跟蹤當前文件夾的好方法是,在跨多個文件夾工作時,在 xterm 標題欄上顯示文件夾名。

例如,可以使用 echo 命令在 xterm 標題欄上顯示一些基本信息。在 shell 提示上輸入 echo "[Ctrl-v][Esc]]2; Hello [Ctrl-v][Ctrl-g]"。注意,[Ctrl-v] 表示按組合鍵 Ctrl-V。輸入這個命令序列,就會在 shell 提示上顯示以下內容:echo "^[]2; Hello ^G"。執行這個命令之後,xterm 標題欄顯示 Hello。清單 12 演示如何在 xterm 標題欄和提示中同時顯示當前文件夾名。


清單 12. 使用 cmdcwd 修改提示並設置 xterm 標題欄
arpan@tintin[/home/arpan1/ibm1]# alias cwdcmd 'set prompt="$user@`hostname`[$cwd]# ";       echo "^[]2;$cwd^G" '  

自動糾正無效的命令用法

tcsh 提供內置變數 correct,這有助於糾正無效的命令用法。例如,如果希望調用 perl,但是輸入的是 prl,tcsh 會提示您糾正它。清單 13 給出一個示例。


清單 13. tcsh 自動糾正輸入
arpan@tintin# set correct=cmd  arpan@tintin# prl   CORRECT>perl (y|n|e|a)? y  ..  arpan@tintin# figner  CORRECT>finger (y|n|e|a)? y  ..  

定期執行特定的命令

系統管理員最常見的任務之一是監視磁碟使用量,並在磁碟使用量接近 100% 時採取措施。tcsh 的一個出色特性使我們能夠輕鬆地定期執行特定的命令。把 periodic 映射到要定期執行的任務,並把 shell 內置變數 tperiod 設置為執行任務的時間間隔(以分鐘為單位)。清單 14 演示如何使用 tperiod 和 periodic。注意,periodic 映射到腳本 checkdiskusage,這個腳本檢查磁碟使用量,tcsh 每 10 分鐘運行它一次。


清單 14. 使用 tcsh 內置變數定期執行命令
arpan@tintin# set tperiod=10  arpan@tintin# alias periodic checkdiskusage  arpan@tintin# cat checkdiskusage  df -k | awk -F" " '{print $5}' | grep "9[0-9]*"  if ($status <> 0) then     mail –s "disk quota exceeded 90%" root@officemail.com  endif  exit $status  

針對每個終端分別設置歷史文件

同一位 UNIX 系統用戶常常從多個終端登錄。為了針對每個終端分別維護命令執行歷史,可以使用 histfile 和 savehist 環境變數。histfile 變數用來指定存儲命令執行歷史的文件;默認設置是 $HOME/.history。savehist 變數讓 tcsh 存儲用戶在 shell 提示上輸入的最後 N 個命令。清單 15 中定義的 histfile 變數指定多個歷史文件,這樣就可以監視多個終端。


清單 15. 使用 histfile 和 savehist 變數存儲用戶的命令歷史
arpan@tintin# tty  /dev/pts/0  arpan@tintin# set savehist=25  arpan@tintin# set histfile=~/.history_`tty | sed –e 's/\//_/g' `  arpan@tintin# echo $histfile  ~/.history_dev_pts_0  

監視運行一個命令花費的時間

為了監視執行一個 UNIX 進程花費的時間,可以設置 time 變數。輸出顯示用戶時間、內核時間和實際流逝時間。清單 16 給出一個示例。

注意,可以用 tcsh 的內置命令 time 產生相同的輸出,但是要對腳本做大量修改 —— 每個命令必須加上前綴 time(例如,time du –sm /opt)。如果使用 time 變數,那麼只需在腳本的開頭加上一行 set time,就可以顯示各個命令的執行時間。


清單 16. 使用 time 顯示各個命令的執行時間
arpan@tintin# cat script  set time  du –sm /opt  df –k /lib  arpan@tintin# tcsh –f ./script  198  /opt  0.628u 0.008s 0:02.00 0.0%      0+0k 0+0io 0pf+0w  Filesystem           1K-blocks      Used Available Use% Mounted on  /dev/sda1             15773312     1125772  13846300   8% /  0.000u 0.004s 0:00.02 0.0%      0+0k 0+0io 0pf+0w  

調試 shell 腳本:在發生錯誤時自動輸出退出值

shell 變數 printexitvalue 是一個很有用的 tcsh 特性,它對腳本調試非常有幫助。在通常情況下,shell 腳本和 UNIX 程序在成功完成時返回零。如果設置這個變數,那麼當腳本或程序返回非零值時 tcsh 會顯示退出狀態,這會指出潛在的錯誤。見清單 17。


清單 17. 使用 printexitvalue 幫助調試
arpan@tintin# set printexitvalue  arpan@tintin# ls /tmp/opt  ls: /tmp/opt: No such file or directory  Exit 2  arpan@tintin# cat error_script  ls –l; return 2  arpan@tintin# ./error_script  ./error_script: line 1: return: can only `return' from a function or sourced script  Exit 1  arpan@tintin# unset printexitvalue; ls /tmp/opt  ls: /tmp/opt: No such file or directory  

注意,在這個變數與一個 shell 腳本結合使用時,顯示的是腳本的非零返回值,而不是腳本內部使用的命令或用戶程序的返回值。

結束語

除了支持 csh 提供的 shell 變數之外,tcsh 還提供了大量 shell 變數和別名。本文主要介紹 tcsh 特有的變數。這裡只討論了一部分變數;更詳細的信息參見 參考資料。 (責任編輯:A6)



[火星人 ] tcsh shell 變數已經有883次圍觀

http://coctec.com/docs/linux/show-post-69085.html