2010年1月17日 星期日

C Shell

C shell 有以下特點:

,可將輸出入重導向
,可用萬用字元指定多個檔案
,提供環境變數以供設定
,整數運算
,可取用使用過的指令
,別名
,提供內建指令用於 shell 程式設計
Job 控制 ( SVR4 開始後才有 )

-----------------------------------------------------------------------------

語法

本章講解的內容是 C shell 獨有的一些符號運用。解說順序如下:

特別檔案
檔名中介符號
引用符號
指令形式
重導向形式

-----------------------------------------------------------------------------

特別檔案

~/.cshrc               每啟動一個 shell 就會執行一次
~/.history              上一次登入時所用過的指令
~/.login              登入後在 .cshrc 後執行
~/.logout              登出時執行
/etc/passwd              供查詢 ~name 所代表的目錄的檔案

-----------------------------------------------------------------------------

檔名中介符號

*                            代表 0 個或更多個的任意符號
?                            代表單一個任意符號
[abc ⋯]              尋找括號中的任一符號,可用 "-" 來指定範圍,如 a-z1-9 等等。
{abcxxx⋯}              將每個由逗號分開的字串展開
~                            目前使用者的目錄
~name                            使用者 name 的目錄

使用範例:

% ls new*                            列出 new new.1
% cat ch?                            ch9 符合,但 ch10 不合
% vi [D-R]*                            所有 D R 開頭的檔案皆符合
% ls {ch,app}?                            先展開,然後尋找 ch1, ch2, app1, app2
% cd ~tom                            切換到 tom 的目錄


-----------------------------------------------------------------------------

引用符號

引用 (quote) 過的符號會失去其特殊意義,而當做一般符號直接處理。下列為 C shell 的特殊符號:

;                            指令分隔符號
&                            背景執行
( )                            指令群集功能 (command grouping)
|                            Pipe
* ? [ ] ~ + - @ !              檔案中介符號
{}                            字串展開,通常不須引用
> < &                            重導向符號
! ^                            用過的指令,快速取代字元
" ' \                            用來引用其他符號的符號
`                            指令取代
$                            變數或指令取代
換行 空白 tab              分隔符號

-----------------------------------------------------------------------------


下列符號可用來進行引用:
" " 任何在雙引號之間的符號,除了下列者皆視為一般符號。
              $ 進行變數取代
              ` 進行指令取代
              " 表示引用之結尾
              \ 將下一個字元視為一般符號
              ! history( 用過的指令記錄 )
              newline 換行
' '              除了驚嘆號 (!)、換行字元(newline)、與另一個單引號之外,兩單引號之間的任何符號均視為一般符號
\              緊接在此符號之後的單一符號將視為一般符號。通常用在雙引號之間來表示一些具有特殊意義的符號,如雙引號(")、錢字號($)、與單引號(')。這個符號也可以用來表示自己(\)、換行符號(newlines)、或空白(space)。若要印出「純」驚嘆號(不是上述有history功能的「驚嘆號」),也可以利用這個符號來表示。


使用範例:

<<<<<<<<<  code  >>>>>>>>


-----------------------------------------------------------------------------



p5-4


指令形式

cmd &                            cmd 放入背景執行
cmd1 ; cmd2              指令列,將兩個指令放在同一行執行
(cmd1 ; cmd2)              shell,將 cmd1 cmd2 視為同一群指令
cmd1 | cmd2              Pipe,將 cmd1 的輸出當做 cmd2 的輸入
cmd1 `cmd2`              指令取代,將 cmd2 的輸出當做 cmd1 的參數
cmd1 && cmd2              AND,若 cmd1 順利執行,則執行 cmd2
cmd1 || cmd2              OR,若 cmd1 沒有順利執行時,則執行 cmd2


使用範例:

% nroff file &                                          將檔案格式化的動做放入背景執行
% cd; ls                                                         依序執行
% (date; who; pwd) > logfile              將所有輸出重導向到 logfile
% sort file | pr -3 | lp               將檔案排序後列在一頁中並列印
% vi `grep -l ifdef *.c`               編輯由 grep 找到的檔案
% egrep '(yes|no)' `cat list`               指定尋找由 list 指定的檔案
% grep XX file && lp file               若找到 XX 檔案則列印
% grep XX file || echo "XX not found"               若找不到 XX 檔案則印出訊息


-----------------------------------------------------------------------------


重導向形式

檔案代碼               名稱                             常用簡稱               一般所使用的裝置
0                            標準輸入               stdin                            鍵盤
1                            標準輸出               stdout                            終端機
2                            標準錯誤               stderr                            終端機

常用的輸出入可用下列方法改變:



簡單重導向形式:

cmd > file              cmd 的輸出寫入 file ( 覆寫 )
cmd >! file              同上,即使noclobber 有設定(set
cmd >> file              cmd 的輸出寫入 file ( 附於檔尾 )
cmd >>! file              同上,即使 noclobber 有設定(set)也會建立檔案
cmd < file               file 內容當作 cmd 輸入
cmd << text              從標準輸入裝置中讀入資料,一直到遇到 text 所指定的字串為止 (text 可存在環境變數中 )。輸入通常直接從鍵盤輸入或是寫在 shell 程式中。一般使用這種格式的指令有 cat, echo,              ex sed。若 text 前後加上引用符號,則不進行變數與指令取代。


-----------------------------------------------------------------------------


多重導向

cmd >& file                            將標準輸出與錯誤都送往 file
cmd >&! file              將標準輸出與錯誤都送往 file,即使 noclobber 有設定
cmd >>& file              將標準輸出與錯誤附加在 file
cmd >>&! file              將標準輸出與錯誤附加在 file 後,即使 noclobber 有設定
cmd1 |& cmd2              將標準輸出與錯誤均送進 pipe
(cmd >f1) 2>f2              將標準輸出導向至 f1,標準錯誤導向至 f2
cmd | tee files              cmd 的輸出分別導向至標準輸出和 files ( 見第二章 tee 的部份 )


使用範例:

% cat part1 > book
% cat part2 part3 >> book
% mail tim < report
% cc calc.c >& error_out
% cc newcalc.c >&! error_out
% grep UNIX ch* |& pr
% (find / -print > filelist) >& no_access

% sed 's/^/XX /g' << "END_ARCHIVE"
This is often how a shell archive is "wrapped",
bundling text for distribution. You would normally
run sed from a shell program, not from the command line.
"END_ARCHIVE"

XX This is often how a shell archive is "wrapped"
XX bundling text for distribution. You would normally
XX run sed from a shell program, not from the command line.

----------------------------------------------------------------------------


變數

本章討論主題如下:

變數取代
變數轉換
內建變數
.cshrc 範例
環境變數

----------------------------------------------------------------------------


p5-6


變數取代


下列式子中如果不需將變數名稱與後面的字元分開時,可以不用 {}

${var}                            取用 var 之值
${var[i]}              取用 var 中第 i 個字,i 可以是單一數字或是一組範圍,m-n-nm- 、或 * -n 1 到第 n 個字,m- 表從第 m 個到最後一個字,i 也可以是個變數,展開後必需符合上面的規則。
${#var}                            取用 var 的長度
${#argv}              取用參數個數
$0                            程式名稱
${#argv[n]}              取用第 n 個指令行參數,n=1-9
${n}                            $argv[*] 相同
$argv[$#argv]              取用最後一個指令行參數
${?var}                            var 已設定則傳回 1,否則傳回 0
$$                            目前 shell 的行程編號,可用來產生暫時檔之檔名,而不容易與其他檔名重覆。
$?0                            若輸入檔名已知,則傳回 1,否則傳回 0
$<                            從標準輸入中讀入一行

使用範例:

將第三個到最後一個參數排序後儲存到暫存檔內

sort $argv[3-] > tmp.$$

僅在互動模式下 ( 必須設定 prompt 變數 ) 才處理 .cshrc 中的指令

if ($?prompt) then
   set commands,
   alias commands,
   etc.
endif


----------------------------------------------------------------------------


變數轉換

除了 $?var$$$?0 $< 外,上列的變數取代後都可以加上以下的變數轉換字串。若需用括號,則必須將轉換字串包括在內。

r              傳回變數的根 ( 除去延伸檔名的部份 )
e              傳回變數的延伸名稱
h              傳回變數的路徑開頭
t              傳回變數的結尾
gr              傳回所有的根 ( 除去延伸檔名的部份 )
ge              傳回所有的延伸名稱
gh              傳回所有的路徑開頭
gt              傳回所有的結尾
q              引用字串變數,將裡面的每個字分開。常用於變數內含不應展開的中介字元的情況下。
x              引用 pattern,展開成字串。

路徑變數轉換使用範例:

下列使用例中的變數如下:

aa={/progs/num.c /book/chap.ps}

取用的部份                             指令                             輸出結果

正常                                           echo $aa              /progs/num.c /book/chap.ps

第二個的根                             echo $aa[2]r                            /book/chap
第二個的路徑開頭               echo $aa[2]h                            /book
第二個的路徑結尾               echo $aa[2]t                            chap.ps
第二個的延伸檔名               echo $aa[2]e                            ps

                                          echo $aar                            /progs/num /book/chap.ps
所有的根                             echo $aagr              /progs/num /book/chap
路徑開頭                             echo $aah                            /progs /book/chap.ps
所有的路徑開頭                            echo $aagh                            /progs /book
路徑結尾                             echo $aat                            num.c /book/chap.ps
所有的路徑結尾                            echo $aagt                            num.c chap.ps
延伸檔名                            echo $aae                            c /book/chap.ps
所有的延伸檔名                            echo $aage                            c ps


引用變數轉換使用範例:
<<<<<  code  >>>


----------------------------------------------------------------------------

p5-8

事先定義的shell變數


要設定 shell 變數有兩種方法,一種是用 var=value 這種形式,另一種只要打 var 將變數啟動即可。


下列表中,等號後的是變數可接受值的類型。但 argvcwd 或是 status 不可設定,由系統自行設定其值,C shell 會自動設定以下變數: argvcwdhomepathpromptshellstatusterm、和 user

argv=(args)              傳給指令或程式的指令列參數,預設為 ()
cdpath=dirs              cd, popd, pushd 指令時所搜尋的目錄,可當做切換目錄之捷徑。
cwd=dir                            目前目錄的完整路徑名稱
echo                            csh -x 指令一樣,會在每次執行指令之前將指令行顯示出來
fignore=(chars)              所要忽略的檔名字尾 ( filec)
filec                            C shell 有個功能,當使用者輸入檔名的一部份時,若按下 ESC 鍵,就可展開成其完整的名稱。若輸入的一部份檔名符合許多個檔案,則打入 EOF 可顯示所有符合的檔案。
hardpaths              使用 dirs 時,將符號連結的完整路徑顯示出來
histchars=ab              定義一個兩字元長的字串,用來當做使用過的指令取代字串。預設為 !
history=n              要在使用過的指令記錄檔中記錄多少指令
home=dir              使用者目錄,由 HOME 設定,~ 符號可用來代替
ignoreeof              忽略由終端機輸入的 EOF 字元,防止使用者不小心登出
mail=(n file)              搜尋新信的檔案,每五分鐘搜尋一次,或是每 n 秒。
nobeep                            輸入的字串符合多個檔案字首時,不發出聲音 ( filec)
noclobber              若檔案已存在,則不進行重導向
noglob                            將檔名展開功能關閉,shell script 中常用
nonomatch              將中介字元視為一般字元,比如 vi ch* 將會產生 ch* 檔,而不會顯示成 "no match"
notify                            若有 job 結束,立刻通知使用者,而不等待下一個提示符號。
path=(dirs)              列出所有搜尋執行命令之路徑。由 PATH 設定,預設為 ( . /usr/ucb /usr/bin)
prompt='str'              提示字串,預設為 %
savehist=n              要在登出時存入 ~/history 檔中的指令數,下次登入時可使用。
shell=file              shell 的路徑,如 /bin/csh
status=n              上一個結束指令的傳回值,內建指令成功則傳回 0,否則傳回 1
term=ID                            終端機形式,/etc/ttytype 設定,與 TERM 相同。
time='n %c'              若指令執行時間超過 n CPU 秒,則顯示使用者時間,系統時間,累計時間和 CPU 百分比。%c 可指定顯示其他的資料。
user=name              USER 設定,為登入者的使用者名稱。
verbose                            指令取代後顯示該指令,和 csh -v 相同


.cshrc 檔的範例

-----<<<<<<<<  僅將 # 開頭者翻譯出  >>>>>>>>>>>>>----------

# 事先定義的變數


# 設定為互動使用



# 這時可打入 cd macros
# 而不用打入全名 cd /usr/lib/macros

# 忽略 object 檔,不必列入 filec 指令中

# 包括使用過的指令編號

p5-10

# 使用者的變數
# 可直接用 cd $man1ls $man1
# 可直接用 vi $a
#              或是 grep string $A


# 別名
# 這裡要用引用符號防止 shell ; 或是 | 展開
# 重新定義 ls 指令
# rm 定義成比較安全的形式


----------------------------------------------------------------------------


環境變數

C shell 有一組環境變數,和內建的 shell 變數不同,嚴格來說不能算是 C shell 的一部份,shell 變數通常只對使用該變數的 shell 有意義,但是環境變數從登入到登出,對每個啟動的 C shell 均有效力,當然也包括每個 shell 中所執行的 shell script 或是程式。

環境變數的設定法如下:

  setenv VAR value

依照慣例 ( 很有虎膽妙算的氣氛吧 !),所有的環境變數都是大寫的,使用者可以自行建立新的環境變數,或是使用下列內建的環境變數。

下列的環境變數更動時,會自動複製到相應的 C shell 變數中。

HOME              使用者目錄,同 home
PATH              搜尋指令的路徑,同 path
TERM              終端機形式,同 term
USER              使用者名稱,同 user

其他環境變數如下:

EXINIT              .exrc 中一樣,是 ex 指令字串,如 set ai,用於 viex
LOGNAME              USER
MAIL              這是郵件的檔案,和 mail 不同的是,mail 僅是檢查是否有新郵件,而這個變數則是提供給郵件程式使用。
PWD              目前目錄,由 cwd 複製而得
SHELL              預設為無,而後設定為與 shell 相同
TERMCAP              此檔案內容為目前使用終端機的游標移動碼,預設為 /etc/termcap


P5-11


運算式



@ifwhile 等中都可以用運算式,用來作數學運算,比較字串,檢查檔案等等,exit
set 也可用來指定運算式,運算式的語法和 C 語言相同,運算子的優先順序如下:

1. * / %
2. + -

其它的運算式請用 () 括起來,若內容有 <, >& 或是 |,則必須加上括號。


-----------------------------------------------------------------------


運算子

下列為運算子的說明:



指定運算子

=                            指定值
+= -=                            加或減後再指定
*= /= %=              乘,除或取餘數後再指定
&= ^= |=              邏輯的 AND/XOR/OR
++                            遞增
--                            遞減



數學運算子

* / %              乘,除,餘數
+ -              加,減



逐位元運算子與邏輯運算子

~              1 的補數
!              邏輯 NOT
<< >>              逐位元向左移,右移
&              逐位元 AND
^              逐位元 XOR
|              逐位元 OR
&&              邏輯 AND
||              邏輯 OR
{ command }              若指令成功則傳回 1,否則傳回 0,注意,這和一般的傳回狀況不同,用 $status 可能比較好。


P5-12


比較運算子

== !=              等於,不等於
<= >=              小於等於,大於等於
< >              小於,大於
=~              左邊的字串符合右邊含有 *? [⋯] pattern
!~              左邊的字串不符合右邊含有 *? [⋯] pattern



檔案檢查運算子

-d file              file 存在且為目錄
-e file              file 存在
-f file              file 存在且為普通檔案
-o file              使用者擁有此檔
-r file               file 存在且可讀
-w file               file 存在且可寫入
-x file               file 存在且可執行
-z file              file 大小為 0
!                                          加上這個驚嘆號可以將上述的意義倒過來


使用範例:

下列例子中使用 @ 指令,並假設 n=4

<<<<<<<<< code >>>>>>>>>>>

下列例子列出 if 或是 while 的第一行

運算式                                          意義
< 左邊是 code>              還有參數 ⋯.
                                          若第一個字是 "Fri" ⋯.             
                                          若檔名不以 .z 或是 .Z 結尾
                                          若第一個參數是 chap 後加上單一字元
                                          若第一個參數是普通檔案 ⋯.
                                          tmpdir 不是目錄 ⋯.
             

-------------------------------------------------------------------

p5-13

使用過的指令


C shell 會把以前用過的指令存在檔案中,稱為 history,可以加以重覆,編輯並執行,history 這個指令會列出所有的指令列表,histcharshistory savehist 這幾個內建
變數也會影響整個 history 的行為,存取 history 列表包括下列三種動作:

指令取代 (! ^)

參數取代 ( 取代指令行中的某幾個指定的參數 )
用轉換字串來取出或取代指令的某一部份


-----------------------------------------------------------------------


指令取代


!              開始進行取代
!!              上一個指令
!N                            history 列表中的第 N 個指令
!-N                            history 列表中的倒數第 N 個指令
!string                            string 開頭的前一個指令
!?string?                            string 的前一個指令
!?string?%                            參數中含有 string 的前一個指令
!$                                                        前一個指令的最後一個參數
!!string                            string 接在前一個指令尾
!N string                            string 接在第 N 個指令尾
!{s1}s2                                          s2 接到以 s1 開頭的前一個指令尾
^old^new^                            快速取代 ; 將前一個指令中的 old 字串換成 new 字串後執行。


-----------------------------------------------------------------------

指令取代使用範例:

假設使用下列指令:

  %3 vi cprogs/01c ch002 ch03

事件號碼               輸入指令               執行的指令

<<<<<<<<<  code   >              >>>>>>



p5-14

-----------------------------------------------------------------------


單字取代


下列轉換字串前都可加上冒號,事件號碼後可加可不加冒號,除非有特別指定。

0              指令名稱
n              n 個參數
^              第一個參數
$              最後一個參數
n-m              n 到第 m 個參數
-m              0 到第 m 個字,同:0-m
n-              n 個到倒數第二個參數
n*              n 個到最後一個參數,同 n-$
*              所有的參數,同 ^-$ 或是 1-$
#              目前到游標所在的位置,無用


-----------------------------------------------------------------------


單字取代使用例

假設使用下列指令:

   %cat ch01 ch02 ch03 biblio back

事件號碼               輸入指令               執行的指令

<<<<<<  code  >              >>>>>>>>>>>>>>>>



History 修飾字串(History Modifier

指令與字的取代可以由下列來修飾:


顯示,取代與引用

p                                          顯示指令但不要執行
s/old/new                            僅修改一次指令的 old 字串取代成 new 字串
gs/old/new              將所有指令的 old 字串取代成 new 字串
&                                          重覆上一次的取代動作 (:s 或是 ^ 指令 ),僅一次
g&                            重覆上一次的取代動作
q                                          引用字串列
x                                          引用個別單字


截斷(truncation

r                            取出第一個讀到的路徑之根
gr              取出所有的路徑之根
e                            取出第一個讀到的路徑之延伸檔名
ge              取出所有的路徑之延伸檔名
h                            取出第一個讀到的路徑開頭
gh              取出所有的路徑開頭
t                            取出第一個讀到的路徑結尾
gt              取出所有的路徑結尾



History 修飾字串使用例

17 個指令是:

%17 cat ch01 ch02 ch03

事件號碼               輸入指令               執行的指令

<<<<<<<<<<<<<<  code  >>>>>>>>>>>>>>>>>>>             



p5-16

內建指令 (C Shell)


--------------------------------------


#


# 號之後同行的任何內容都予以忽略,其實這並不是個 " 指令 ",而是註解符號,第一行的第一個字元若是 # 時,代表這是 C shell script


--------------------------------------


#!shell


放置於 shell script 的第一行,將由 shell 所指定的 shell 來啟動此 script,可以加上使用參數,例如:


#!/bin/csh -f


--------------------------------------



Null 指令,程式的傳回值為 0


--------------------------------------


alias [name[command]]


name 指定為 command 的別名,若無 command 參數,則印出 name 所代表的指令,若連 name 都沒有,則印出所有的別名定義,指令行中也可以定義別名,但多半寫在 .cshrc 中,一登入即可使用( 見前幾章的 .cshrc 範例 )。別名定義中可以用一些取代字串,如 \!* 表是所有的指令行參數,\!^ 表示第一個參數,\!$ 表示最後一個,和 history 列表的用法一樣,name 可以是任何名稱,包括 UNIX 指令,一旦用 UNIX 指令名稱作為 name,則該 name 失去原來的指令意義,要加上 \name 才是原來的指令。請參照 unalias

例如:

設定 X Windows xterm 的視窗大小

alias R 'set noglob; eval 'resize'; unset noglob'

列出名稱中包含 ls 字串的別名

  alias | grep ls

所有的指令列參數均執行 nroff

  alias ms 'nroff -ms \!*'

將第一個參數所指定的檔案加以複製

  alias back 'cp \!^ \!^.old'

用原來的 ls,而非別名 ls

  % \ls

--------------------------------------


bg[jobIDs]


將目前的 job 或是 jobIDs 放入背景執行,詳見 job 控制功能。


範例:

要將某個執行費時的程式放入背景,一開始可用:

4% nroff -ms report
CTRL-Z


然後用下列任一指令均可:

5% bg
5% bg %              目前的 job
5% bg %1              1 job
5% bg %nr              nr 開頭的 job
5% % &


--------------------------------------

break

從最內層的 foreachwhile 迴圈中跳出一層。


--------------------------------------

breaksw

switch 中跳出,會從 endsw 後開始執行


--------------------------------------

case pattern

指定 switch 內每種不同的pattern


--------------------------------------

cd [dir]

將目前目錄切換到 dir,若 dir 僅為相對的路徑,則開始搜尋 CDPATH 中的目錄,看其中是否有 dir


--------------------------------------

chdir [dir]

cd 相同,若將 cd 設為別名時,可直接使用這個


--------------------------------------

continue[n]

直接跳到最近的 while 或是 foreach 繼續執行


--------------------------------------

default

定義 switch 內若無符合狀況時的預設動作 ( 通常放在最後一個 )


--------------------------------------
dirs [-l]

列出使用過的目錄堆疊,從目前目錄開始,-l 會將 ~ 符號(也就是使用者主目錄)展開成實際的路徑名稱,見 pushd popd


--------------------------------------
echo[-n][string]

string 顯示在標準輸出上 ; 若加上 -n 參數,輸出不加上換行字元,若無 string,則顯示一行空白,echo 中不可以使用特殊的 escape 字元,見第二章與第四章的 echo


--------------------------------------

end

foreach switch 的結尾保留字


--------------------------------------

endif

if 敘述的結尾保留字


--------------------------------------

eval args

一般情況下均於 shell script 中使用 eval 指令,args 則為一行指令,其中含有 shell變數,eval 會先強迫進行變數取代,然後執行展開後的指令。當 shell 變數含有輸出入重導向或是別名,或是有其它 shell 變數時,這種先展開後執行的方式很好用,( 比如說,通常重導向符號的優先順序高於展開變數,所以含有重導向符號的變數就必須先用 eval 加以展開,不然重導向符號會變成沒有意義 )Bourne shell 的說明在第四章的 eval,其餘範例如下 ( 相關見 alias)

範例:

下列可以放入 .login 檔中,每次登入可設定 xterm 的屬性。

              set noglob
              eval 'tset -s xterm'
              unset noglob


下列指令可顯示 eval 的效果:

% set b='$a'
% set a=hello

% echo $b              讀入一次指令行
$a
% eval echo $b              讀入兩次指令行
hello


--------------------------------------

exec command

command 代替目前的 shell 繼續執行下去,


--------------------------------------

exit [(expr)]

結束 script 時傳回值由 expr 決定。傳回值可以是 0 ( 正常結束,表執行成功 ) 或是非 0 的值 ( 不正常結束,表執行失敗或有錯誤 ),若不指定 expr 值,則使用 status 變數之值。exit 用於指令列時,可用來關閉視窗 ( 登出 )


--------------------------------------

fg[jobIDs]

將目前的 job 或是 jobID 拿到前景執行,詳見 "job 控制功能 "

範例:
若要將 vi 正在編輯的 job 暫停,可以按 Ctrl-Z,而要繼續可用下列任一指令:

  8% %
  8% fg
  8% fg %
  8% fg %vi              將開頭與 vi 相符合的 job 帶回前景執行




--------------------------------------

foreach name(wordlist)
commands
end

將變數 name 依序指定成 wordlist 中的每個值,然後用該值執行 command,可以將 foreach 當做 C shell 指令列下的指令使用 ( 如第一例 ),也可以在 shell script 中使用 ( 如第二例 )


將大寫開頭的檔名全部更名
<<<<<  code >>>>>


檢查每個指令行參數是否為選項
<<<<  code  >>>>


--------------------------------------

glob wordlist

wordlist 取代,和 echo 類似,但不可使用 \ 符號,每個字的結尾皆為 null 字元,glob 通常用於 shell script 中,用來將變數 " 轉換型態 ",使其在接下來的 script 中保持不變。


--------------------------------------

goto string

跳到以 "string" 為開頭的行去,然後從該處繼續往下執行。goto 時,string 本身可以是變數或是某個檔名的 pattern,可是跳過去的標籤必須明確定義,且不可以在 foreach 或是 while 中。


--------------------------------------
hashstat

列出 hash table 使用 path 變數找到指令的成功程度。



--------------------------------------
history [options]

列出使用過的指令,其用法前幾章說明過。


options

  -h              單純列出使用過的指令
  -r              反向列出使用過的指令
   n              只列出前 n 個使用過的指令,而不管 history 變數所指定的個數。

範例:
儲存並執行前五個指令

              history -h 5 > do_it
              source do_it


--------------------------------------

if

條件敘述的起頭,最簡單的形式如下


if (expr) cmd

下列為三種更複雜的狀況:

<<<<<  code   >>>>>>>>>>>>



在最簡單的形式中,若 expr 為真則執行 cmd,否則什麼也不做 ( 但有個小 bug,就是若 cmd 包括重導向,則重導向會執行 ),其它形式可執行一個或多個指令,若 expr 為真,則繼續執行 then 以後的指令,若 expr 不為真,則跳往 else 的部份去執行 ( 或是往 else if 繼續檢查並執行 ),請見本章前面 " 運算式 " 的部份,或是 shift while

範例:

若無指令行參數,則進行預設動作:

<<<  code  >>>>>>>>


--------------------------------------
jobs [-l]

列出所有正在執行或是待機中的 job,加上 -l 選項可以列出行程編號(process ID)。例如,妳可以檢查一個很冗長的編譯工作是否仍在執行,或是一個文字格式化的工作是否還在執行。你可以在登出之前使用這個指令來檢查目前的狀態,相當有用。


--------------------------------------
kill [options] ID

將所指定的行程 ID 或是 job ID 予以終止,必需是特權使用者或是擁有該行程才可以使用此指令,此內建指令和 /bin/kill 類似,並且允許你用符號式的工作名稱(而非只能使用工作的數字ID)。若用 9 做為 signal 號碼,則是直接停掉該行程或是 job。請參看本章最後 job 控制功能之說明。

Options

  -l              列出所有的 signal 名稱
  -signal              ps -f 可找到 signal 的號碼,用 kill -l 找出 signal 的名稱,                           


Signals

signal 定義在 /usr/include/sys/signal.h 中,此處列出者不含前面的 SIG 字首。

HUP              1              hangup( 掛斷連線 )
INT              2              interrupt( 中斷 )
QUIT              3              quit( 退出 )
ILL              4   非法指令
TRAP              5              trace trap
IOT              6              IOT 指令
EMT              7              EMT 指令
FPE              8   浮點運算所產生的例外狀況
KILL              9              kill
BUS              10  bus error
SEGV              11              segmentation violation( 節區錯誤 )
SYS              12              系統呼叫參數錯誤
PIPE              13  寫入的 pipe 沒有行程讀取
ALRM              14               鬧鐘
TERM              15              軟體終止,預設的 signal
USR1              16              使用者自訂 signal 一號
USR2              17              使用者自訂 signal 二號
CLD              18              子行程終止
PWR              19              斷電後重新開機

範例:

若使用下列指令:

              44% nroff -ms report &

可用下列任一方式停止

45% kill 19536                            Process ID
45% kill %                            目前的 job
45% kill %1                            1 job
45% kill %nr                            開頭的字串
45% kill %?report              指令中的字串


--------------------------------------

limit [-h] [resource[limit]]

列出或是設定目前的行程與其產生的子行程,所控制或使用的一些資源的上限,若無 limit參數,則列出目前資源的上限,若無 resource 參數,則列出目前所有 resource 的上限,預設狀況是列出或是設定目前的限制,而用 -h 則用強制限制,強制限制的上限是真正的上限,只有特權使用者可以提高其強制限制上限,見 unlimit

Resource

  cputime              簡稱 cpu,為最多 CPU 可用的秒數
  filesize              單一檔案的最大大小
  datasize              資料節區加上堆疊節區的最大大小
  stacksize              堆疊節區的最大大小
  coredumpsize              core dump 檔案的最大大小

Limit

   這是一個數字後面加上一個單位

   cputime              nh(n 小時 )
                            nm(n 分鐘 )
                            mmss( 分:秒 )
   其它               nk(n kbytes,預設 )
                            nm(n Mbytes)


--------------------------------------
login [user| -p}

user shell /bin/login 代替,-p 可用來保存環境變數。


--------------------------------------
logout

登出


--------------------------------------

nice [± n] command

command 的執行優先權予以改變,若無 command 參數,則改變目前 shell 的優先權,( 見第二章 nice),優先權範圍為 -20 20,預設為 4,數字越小優先權越高,表示執行速度越快。

+n              將目前的優先權 +n,降低優先權
-n              將目前的優先權 -n,提升優先權,僅特權使用者可使用。


--------------------------------------

nohup [command]

登出後也不將此指令結束,若不加上 command,則該 shell script 不會因為登出而結束。


--------------------------------------
notify [jobID]

背景程式一結束就通知使用者,而不等前景程式結束,若無 jobID,則假設為目前的背景程式。


--------------------------------------

onintr lable
onintr -
onintr


此為 On interrupt,和 Bourne shell trap 2 trap "" 2 指令相似,是供 shell script 處理中斷用的,第一種形式下,一旦收到中斷,就會跳到 label 處繼續執行,第二種形式告訴 script 忽略中斷,這可以放在一些不可中斷的程式碼之前,比如移動檔案等等,第三種形式會將中斷狀態恢復到使用 onintr - 之前的狀態。

範例: < 僅翻譯 # 開頭者 >

# 遇到中斷就跳到 "cleanup"
# shell script 指令
# 中斷的標籤
# 忽略之後的中斷
# 將所建立的檔案刪除
# 結束並傳回值




--------------------------------------


popd [+n}
將最後 n 個使用過的目錄路徑從堆疊中移去,若無 n 則移去一個,目前的目錄號碼為 0,排在最左邊。


--------------------------------------

pushd name
pushd [+n}
pushd


第一種形式會將 name 加入堆疊中,並將目前目錄切換至 name,第二種形式會將整個堆疊中第 n+1 個目錄左移到開頭,並將其切換為目前目錄,若無參數,pushd 會將前兩個目錄交換,並切換至新目錄,見 dirs popd

範例:

%5 dirs
/home/bob /usr
%6 pushd /etc                            /etc 加入堆疊
/etc /home/bob /usr
%7 pushd +2                            切換到第三個目錄
/usr /etc /home/bob
%8 pushd                            將前兩個互換
/etc /usr /home/bob
%9 popd                            將目前目錄去除 ; 切換至下一個目錄
/usr /home/bob


--------------------------------------

rehash

path 變數的 hash table 重新計算,每次建立一個新指令都需進行一次 rehash,這可以讓 path 變數找到該指令然後執行,若加入的新指令,其路徑不在 path 中,則先將其路徑加入 path 後再進行 rehash,見 unhash


--------------------------------------

repeat n command

執行 command n

範例:

列印三份 memo

              % repeat 3 pr memo | lp

從終端機讀入 10 行然後存在 item_list

              % repeat 10 line > item_list

template 接到 report 檔後 50

              % repeat 50 cat template >> report

--------------------------------------

set variable=value
set variable[n]=value
set

variable 變數設定為 value 值,若值不只一個,則將變數設定為多值串列 (list),若給定 n 值,則將變數裡的第 n 個字 ( 變數本身必需有那麼多個字 ) 設定為 value 值,無參數時,列出所有設定的變數名稱與其值,見本章前幾節有關內建變數的部份。

範例:

              設定為一個文字列
                            將第三個字設定為 maybe
                            設定變數
                            設定數個變數
                            blank 設定為 null



--------------------------------------

setenv [name[value]]

將環境變數 name 設定為 value 值,按照慣例,name 必需是全大寫,value 可以是一個單字或是引用的字串,若無 value,則設定為 null,若無參數時,將所有環境變數與值列出,USERTERMPATH 變數不需設定,因為系統會自動由 user term path 複製過來,見前面的 " 環境變數 "


--------------------------------------
shift[variable]

若有 variable 參數,則將參數中的值予以左移,如 name[2] 變成 name[1],若無參數,則左移指令行參數,$2 變成 $1shift 通常用於 while 迴圈,請見 while 的使用例。


範例:

<<<>>               # 還有參數
<<>>>
<<<>>>              # 取用下一個參數


--------------------------------------

source [-h] script

C shell script 中讀取指令並執行,-h 會將這些指令加入 history 但不執行。

範例:
source ~/ .cshrc



--------------------------------------

stop [jobIDs]

jobIDs 指定的背景 job 暫停 ; suspend CTRL-Z 可互換使用,見 "Job 控制功能 "


--------------------------------------
suspend

CTRL-Z 相同,常用來停止 su 指令,Korn shell 中無法使用。


--------------------------------------
switch

根據變數的值來選擇相應的動作與指令群,若選擇超過三個,switch 就比 if-then-else來得方便,若 string pattern1 相符,則執行 cmds1,若符合 pattern2 則執行 cmds2,以此類推,若全不符合,則執行 default 的部份,string 可以是指令取代,變數取代或是展開的檔名,Pattern 可以含有 *? [..] 等等,breaksw 是用於每個指令群,在執行完指令後跳出整個 switch 結構用的 ( 若不跳出則每項都會比較,可能會造成重複執行。) 下列的例子是用來處理第一個指令行參數用的:

<<<<  code  >>>>>>


--------------------------------------
time [command]

執行 command,並顯示此指令所使用的累計時間單位為秒,若不用 command 參數,則用來計算 shell script 所使用的時間。


--------------------------------------
umask[nnn]

顯示新檔案的 mask 或是將 mask 設定為八進位的 nnn 值,這個 mask 會決定那些 bit 會關閉,比如 umask 002 會產生 rw-rw-r-- 這樣的檔案存取屬性,umask 也是 UNIX 的指令,見第二章。


--------------------------------------
unalias names

names 從別名中移除,見 alias


--------------------------------------
unhash

將內部的 hash table 移除,C shell 會停止使用 hash table,並在使用指令時去 path 變數指定的路徑中一個一個找,見 rehash


--------------------------------------
ulimit resource

除去 resource 資源的限制,若不加參數,則除去所有資源的限制,見 limit


--------------------------------------

unsetenv variables

將一個或多個 variables 變數的定義予以移除,variables 參數可以利用檔名中介符號(filename metacharacter)來指定,見 set


--------------------------------------
unsetenv variable

除去一個環境變數,不可使用檔名中介符號,見 setenv


--------------------------------------
wait [ID]

先停止執行,直到背景的行程結束才繼續,或是等 ID 結束後才繼續。


--------------------------------------
while (expressions)
do
              commands
done

只要 expressions 條件成立時,重覆執行 commandsbreak continue 可以用來停止或繼續該迴圈,見 shift 的例子。

範例:

set user = (alice bob carol ted)
while ($argv[1] != $user[1])
  # 輪流檢查每個使用者看是否符合
  shift user
  # 若檢查完都沒有符合的....
  if ($#user ==0) then
              echo "$argv[1] is not on the list of users"
              exit 1
  endif
end             

--------------------------------------------------------------------------

@ variable=expression
@ variable[n]=expression
@

expression 運算式的結果設定給 variable,或是 variable 的第 n 個元素,若無參數,則列出所有的 shell 變數和其值 ( set 一樣 )expression 的用法見前面的 " 運算式 ",下列為兩種特殊的 @ 用法:

@ variable++ 將變數加 1
@ variable-- 將變數減 1

--------------------------------------

Job 控制功能

加上 job 控制功能後,就可以將程式從前景放入背景或是從背景放入前景執行,也可以將程式暫停,C shell job 控制指令如下:

bg              job 放入背景
fg              job 放入前景
jobs              列出 jobs
kill              結束 job
notify              背景程式結束時通知使用者
stop              將背景的 job 暫停
CTRL-Z              將背景程式暫停,然後用 fg 或是 bg( 有些終端機的暫停字元不同 )

許多 job 的指令都需用 jobIDs 當做參數,這些參數可用下列代號代表:

%n              job 號碼 n
%s              s 字串開頭的 job( 指指令列以 s 字串開頭 )
%?s              job 指令行中含有 s 字串者
%%              目前的 job
%              同上                                         
%+              同上
%-              前一個 job


呼叫 Shell

C shell 可以於指令列啟動,指令如下:

csh [options] [arguments]             

csh 的語法與 C 語言類似,可從終端機或是檔案執行指令。-n -v -x 等選項在對 script 除錯時很有用。

options

  -b                            將其它的指令行參數給其它的指令使用,而非 csh
  -c                             從第一個檔名參數中執行指令
  -e                            若指令有錯誤則跳出
  -f                            快速啟動,不處理 .login 或是 .cshrc
  -i                            建立互動 shell,用提示符號來提示輸入
  -n                            parse 指令但不執行
  -s                            從標準輸入讀指令
  -t                            執行完一個指令後就跳出
  -v                            執行指令前顯示指令行,但只展開 history 取代,其它如指令與變數取代均不展開,和設定 verbose 相同。
  -V                            同上,加上顯示 .cshrc
  -x                            執行指令前顯示指令行,且展開所有如指令與變數取代,和設定 echo 相同,-x 常與 -v 一起使用。
  -X                            同上,但多顯示 .cshrc

1 則留言:

推到 Twitter!
推到 Plurk!
推到 Facebook!