變量($、echo)以及io重定向(< 、>、 >>)

2.3 一個簡單的腳本

who命令可以告訴你現在系統有誰登陸:

[plain] view plaincopy
  1. [root@localhost ~]# who  
  2. root     pts/2        2012-05-05 09:38 (192.168.0.83)  
  3. root     pts/3        2012-05-05 09:38 (192.168.0.83)  

利用wc(字數計算)程序,它可以算出行數(line),字數(word),字符數(character)。在此例中,我們用的是wc -l 

[plain] view plaincopy
  1. [root@localhost ~]# who|wc -l  
  2. 2                                      //計算用戶個數  

|(管道)符號可以在兩個程序之間建立管道(pipeline):who的輸出,成了wc的輸入,wc所列出的結果就是已登錄用戶的個數

下一步則是把管道轉變成一個獨立的命令。方法是把這條命令輸入一個一般的文件中,然後使用chmod爲該文件設置執行權限,如

[plain] view plaincopy
  1. [root@localhost ~]# vim test_who //建立文件
  2. #! /bin/sh -
  3. who | wc -l                      //程序的內容  
[plain] view plaincopy
  1. [root@localhost ~]# chmod +x test_who //讓文件擁有執行的權限  
  2. [root@localhost ~]# ./test_who //執行測試  
  3. 2                            //輸出我們要的結果  


2.5.2 變量

在Shell的世界裏,變量值可以是(而且通常是)空值,也就是不含任何字符

Shell變量名稱的開頭是一個字母或下劃線符號,後面可以接着任意長度的字母,數字或者下劃線。

[plain] view plaincopy
  1. [root@localhost ~]# vim test_var  
  2. [root@localhost ~]#   
  3. #! /bin/sh -
    myvar="hello word"
    echo $myvar
    echo -n "請輸入參數:"\
    echo $PATH
  4. printf "The first program always prints ' %s,%s! '  \n" hello world 11                                                                            
變量賦值的方式爲:先寫變量名稱,緊接着=字符,最後是新值,中間完全沒有任何空格。當你想取出Shell變量的值時,需要變量名稱前面加上$字符,當所賦予的值內含空格時,請加上引號:

表 2-2 echo的轉義序列

序列 說明
\a 警示字符,通常是ASCII的BEL字符
\b 退格
\c 輸出中忽略最後的換行符(Newline)。這個參數之後的任何字符,包括接下來的參數,都會被忽略掉(不打印)
\f 清除屏幕(Formfeed)
\n 換行
\r 回車
\t 水平製表符
\v 垂直製表符
\\ 反斜槓字符
\a序列通常用來引起用戶的注意;\0ddd序列最有用的地方,就是通過送出終端轉義序列進行(非常)原始的光標操作。但不建議這麼做。

2.5.4 華麗的printf輸出

printf不像echo那樣會自動提供一個換行符號。你必須顯示地將換行符號指定成\n

第一部分是一個字符串,用來描述輸出的排列方式,最好爲此字符串加上引號。此字符串包含了按 字面顯示的字符(characters to be printed literally)以及格式聲明(format specifications),後者是特殊的佔位符(placeholders),用來描述如何顯示相應的參數(argument)。

第二部分是與格式聲明相對應的參數列表(argument list),例如一系列的字符串或變量值。格式聲明分成兩部分:百分比符號(%)和指示符(specifier)。最常用的格式指示符(format specifier)有兩個,%s用於字符串,而%d用於十進制整數。


2.5.5 基本的I/O重定向

程序應該有數據的來源端,數據的目的端(數據要去的地方)以及報告問題的地方,它們分別被稱爲 標準輸入(standard input)、標準輸出(standard output)、以及標準錯誤輸出(standard error)

默認的標準輸入、標準輸出以及標準錯誤輸出都是終端



在用戶登錄系統時,UNIX變將默認的標準輸入、輸出及錯誤輸出安排成你的終端。


2.5.5.1 重定向與管道

Shell提供了數種語法標記,可用來改變默認I/O的來源端與目的端

以<改變標準輸入

program < file 可將program的標準輸入修改爲file:

tr  -d '\r' < dos-file.txt

以>改變標準輸出

program > file 可將program的標準輸出修改爲file:

tr -d '\r' < dos-file.txt > UNIX-file.txt

這條命令會先以tr將dos-file.txt裏的ASCII carriage-return(回車)刪除,在將轉換完成的數據輸出到UNIX-file.txt。dos-file.txt裏的原始數據不會有變化。

> 重定向符(redirector)在目的文件不存在時,會新建一個。然而,如果目的文件已存在,它就會被覆蓋;原本的數據都會丟失

以>>附加到文件

program>>file可將program的標準輸出附加到file的結尾處。

如同>,如果目的文件不存在,>>重定向符便會新建一個。然而,如果目的文件存在,它不會直接覆蓋掉文件,而是將程序所產生的數據附加到文件結尾處:

      

以|建立管道

program1 | program2 可將program1的標準輸出修改爲program2的標準輸入。


tr

語法

tr [options]source-char-listreplace-char-list

用途

轉換字符。例如,將大寫字符轉換成小寫。選項可讓你指定所要刪除的字符,以及將一串重複出現的字符濃縮成一個

常用選項

-c

取source-char-list的反義。tr要轉換的字符,變成未列在source-char-list中的字符。此項通常和-d或-s配合使用

        -C

        與-c相似,但所處理的是字符(可能是包含多個字節的寬字符),而非二進制的字節值。

        -d

自標準輸入刪除source-char-list裏所列的字符,而不是轉換它們。

-s

濃縮重複的字符。如果標準輸入中連續重複出現source-char-list裏所列出的字符,則將其濃縮成一個。

行爲模式

如同過濾器:自標準輸入讀取字符,再將結果寫到標準輸出

舉例:

[plain] view plaincopy
  1. [root@localhost ~]# vi test1.txt  
  2. test1 1  
  3.   
  4. test2 2  
  5.   
  6. test3 3  
  7.   
  8. test4 4  
  9.   
  10. test5 5  
[plain] view plaincopy
  1. [root@localhost ~]# tr -d '\n' < test1.txt  
  2. test1 1test2 2test3 3test4 4test5 5  

警告

根據POSIX標準的定義,-c處理的是二進制字節值,而-C處理的是現行locale所定義的字符。

注意:構造管道時,應該試着讓每個階段的數據量變的更小

例如,使用sort排序之前,先以grep找出相關的行;這樣可以讓sort少做些事。


.

2.5.6 基本命令查找

Shell會沿着查找路徑$PATH來尋找命令。$PATH是一個以冒號分隔的目錄列表,你可以在列表所指定的目錄下找到所要執行的命令。

默認路徑(default path)至少包含/bin與/usr/bin,或許還包含存放X Windows程序的/usr/X11R6/bin,以及供本地系統管理人員安裝程序的/usr/local/bin

名稱爲bin的目錄用來保存可執行文件,bin是binary的縮寫,也可以直接把bin解釋成相應的英文字義--存儲東西的容器;

如果你要編寫自己的腳本,最好準備自己的bin目錄來存放它們,並且讓Shell能夠自動找到它們。這不難,只要建立自己的bin目錄,並將它加入$PATH中的列表即可:

[plain] view plaincopy
  1. [root@localhost ~]# cd ~  
  2. [root@localhost ~]# mkdir bin  
  3. [root@localhost ~]# mv /usr/  
  4. bin/      include/  lib/      man/      src/      X11R6/      
  5. etc/      java/     libexec/  sbin/     tmp/        
  6. games/    kerberos/ local/    share/    ucb/        
  7. [root@localhost ~]# mv /usr/ucb/nusers ./bin/  
  8. [root@localhost ~]# PATH=$PATH:$HOME/bin  
  9. [root@localhost ~]# nusers  
  10. 1  
  11. [root@localhost ~]#   
要讓修改永久生效,在.profile文件中把你的bin目錄加入$PATH,而每次登陸時,Shell都將讀取.profile文件,例如:

PATH=$PATH:$HOME/bin

在$PATH裏的空項目(empty component)表示當前目錄(current directory)。空項目位於路徑值中間時,可以用兩個連續的冒號來表示,如果將冒號直接置於最前端或者尾端,可以分別表示查找時最優先查找或最後查找當前目錄:

PATH=:/bin:/usr/bin //先找當前目錄

PATH=/bin:/usr/bin: //最後找當前目錄

PATH=/bin:/usr/bin //當前目錄居中

如果你希望將當前目錄納入查找路徑(search path),更好的做法是在$PATH中使用點號(dot)

空項目在可移植性上有點問題

一般來說,你根本就不應該在查找路徑中放進當前目錄,因爲這會有安全上的問題。



發佈了89 篇原創文章 · 獲贊 13 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章