Shell教程(五):替代、引用机制、输入输出重定向
替代是什么?
Shell當它遇到一個表達式,其中包含一個或多個特殊字符進行替代。
例子:
下面的例子,同時使打印取代的其值的變量的值。同時“ ”是一個新行取代:
#!/bin/sh ? a=10 echo -e "Value of a is $a "這將產(chǎn)生下面的結果。這里-e選項可以解釋反斜杠轉(zhuǎn)義。
Value of a is 10下面是結果沒有-e選項:
Value of a is 10這里echo命令可以用在以下轉(zhuǎn)義序列:
| 轉(zhuǎn)義 | 描述 |
| \ | backslash |
| a | alert (BEL) |
| ? | ? backspace |
| c | suppress trailing newline |
| f | form feed |
| ? | new line |
| ? | carriage return |
| ? | horizontal tab |
| v | vertical tab |
可以使用-E選項禁用解釋反斜杠轉(zhuǎn)義(默認)。
您可以使用-n選項來禁用插入新行。
命令替換:
命令替換shell執(zhí)行的機制,一組給定的命令,然后替代它們的輸出在命令。
語法
執(zhí)行命令替換的命令時,被給定為:
`command`當執(zhí)行命令替換,確保您使用的是反引號,不是單引號字符。
例子:
命令替換一般是用一個命令的輸出分配給一個變量。下面的例子演示命令替換:
#!/bin/sh ? DATE=`date` echo "Date is $DATE" ? USERS=`who | wc -l` echo "Logged in user are $USERS" ? UP=`date ; uptime` echo "Uptime is $UP"這將產(chǎn)生以下結果:
Date is Thu Jul? 2 03:59:57 MST 2009 Logged in user are 1 Uptime is Thu Jul? 2 03:59:57 MST 2009 03:59:57 up 20 days, 14:03,? 1 user,? load avg: 0.13, 0.07, 0.15變量替代:
變量替換可使Shell程序員操縱變量的值,根據(jù)其狀態(tài)。
這里是所有可能的替換如下表:
| 格式 | 描述 |
| ${var} | Substitue the value of?var. |
| ${var:-word} | If?var?is null or unset,?word?is substituted for?var. The value of?var?does not change. |
| ${var:=word} | If?var?is null or unset,?var?is set to the value of?word. |
| ${var:?message} | If?var?is null or unset,?message?is printed to standard error. This checks that variables are set correctly. |
| ${var:+word} | If?var?is set,?word?is substituted for var. The value of?var?does not change. |
例子:
下面的例子顯示各種狀態(tài),上述替代:
#!/bin/sh ? echo ${var:-"Variable is not set"} echo "1 - Value of var is ${var}" ? echo ${var:="Variable is not set"} echo "2 - Value of var is ${var}" ? unset var echo ${var:+"This is default value"} echo "3 - Value of var is $var" ? var="Prefix" echo ${var:+"This is default value"} echo "4 - Value of var is $var" ? echo ${var:?"Print this message"} echo "5 - Value of var is ${var}"這將產(chǎn)生以下結果:
Variable is not set 1 - Value of var is Variable is not set 2 - Value of var is Variable is not set ? 3 - Value of var is This is default value 4 - Value of var is Prefix Prefix 5 - Value of var is Prefix?
?
元字符:
UNIX Shell提供各種元字符有特殊的意義,同時利用他們在任何Shell腳本,并導致終止一個字,除非引用。
舉個例子: ?匹配一個單一的系統(tǒng)字符,而列出文件中的目錄和*匹配多個字符。下面是一個清單shell特殊字符(也稱為元字符):
* ? [ ] ' "? $ ; & ( ) | ^ < > new-line space tab它與前可能被引用的字符(例如,放置自身) .
例子:
下面的例子,顯示了如何打印 ?a?*?或a??:
#!/bin/sh ? echo Hello; Word這將產(chǎn)生下面的結果。
Hello ./test.sh: line 2: Word: command not found ? shell returned 127現(xiàn)在,讓我們嘗試使用帶引號的字符:
#!/bin/sh ? echo Hello; Word這將產(chǎn)生以下結果:
Hello; Word$符號是一個元字符,所以它必須被引用,以避免特殊處理:
#!/bin/sh ? echo "I have $1200"這將產(chǎn)生以下結果:
I have $1200是以下四種形式引用:
| 引用 | 描述 |
| Single quote | All special characters between these quotes lose their special meaning. |
| Double quote | Most special characters between these quotes lose their special meaning with these exceptions: ·???????? $ ·???????? ` ·???????? $ ·???????? ' ·???????? " ·???????? \ |
| Backslash | Any character immediately following the backslash loses its special meaning. |
| Back Quote | Anything in between back quotes would be treated as a command and would be executed. |
單引號:
考慮echo命令,其中包含許多特殊的shell字符:
echo <-$1500.**>; (update?) [y|n]將在每個特殊字符前的反斜杠是繁瑣的,使該行難以閱讀:
echo <-$1500.**>; (update?) [y|n]有一個簡單的方法來引用一大組字符。將一個單引號(')的開頭和結尾的字符串:
echo '<-$1500.**>; (update?) [y|n]'單引號內(nèi)的任何字符均以一個反斜杠,就好像是在前面的每個字符。所以,現(xiàn)在這個echo命令將顯示正確。
如果要輸出一個字符串內(nèi)出現(xiàn)一個單引號,你不應該把單引號內(nèi)的整個字符串,而不是對子進行使用反斜杠()如下:
echo 'It's Shell Programming'雙引號:
嘗試執(zhí)行以下shell腳本。這個shell腳本使用單引號:
? VAR=ZARA echo '$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]'這將產(chǎn)生以下輸出結果:
$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]所以這不是你想顯示什么。很明顯,單引號防止變量替換。如果想替換的變量值和倒置逗號如預期那樣運作,那么就需要在雙引號命令如下:
VAR=ZARA echo "$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]"這將產(chǎn)生以下結果:
ZARA owes <-$1500.**>; [ as of (07/02) ]雙引號帶走下列以外的所有字符的特殊含義:
·????????$ 參數(shù)替代。
·????????用于命令替換的反引號。
·????????$?使字面美元標志。
·????????` 使文字反引號。
·????????" 啟用嵌入式雙引號。
·????????\ 啟用嵌入式反斜杠。
·????????所有其他字符是文字(而不是指定)。
單引號內(nèi)的任何字符均以一個反斜杠,就好像是在前面的每個字符。所以,現(xiàn)在這個echo命令將顯示正確。
如果要輸出一個字符串內(nèi)出現(xiàn)一個單引號,不應該把單引號內(nèi)的整個字符串,而不是對子進行使用反斜杠()如下:
echo 'It's Shell Programming'反引號:
把反引號之間的任何shell命令將執(zhí)行命令
語法
下面是一個簡單的語法,把反引號之間的任何Shell命令:
例子:
var=`command`例子:
繼執(zhí)行date命令,產(chǎn)生的結果將被存儲在 DATA 變量。
DATE=`date` ? echo "Current Date: $DATE"這將產(chǎn)生以下輸出結果:
Current Date: Thu Jul? 2 05:28:45 MST 2009?
?
大多數(shù) Unix 系統(tǒng)命令從終端的輸入和發(fā)送所產(chǎn)生的輸出返回??到您的終端。一個命令通常從一個地方叫標準輸入,默認情況下,這恰好是你的終端讀取輸入。同樣,一個命令通常寫入其輸出到標準輸出,這也是默認情況下,從你的終端。
輸出重定向:
通常用于標準輸出命令的輸出可以很容易地轉(zhuǎn)移到一個文件中代替。這種能力被稱為輸出重定向:
如果記號> file附加任何命令,通常寫入其輸出到標準輸出,該命令的輸出將被寫入文件,而不是你的終端:
檢查使用 who 命令,將完整的輸出重定向命令在用戶文件。
$ who > users請注意,沒有輸出出現(xiàn)在終端中。這是因為輸出已被重定向到指定的文件從默認的標準輸出設備(終端)。如果想檢查用戶的文件,然后將完整的內(nèi)容:
$ cat users oko???????? tty01?? Sep 12 07:30 ai????????? tty15?? Sep 12 13:32 ruth??????? tty21?? Sep 12 10:10 pat???????? tty24?? Sep 12 13:07 steve?????? tty25?? Sep 12 13:03 $如果命令輸出重定向到一個文件,該文件已經(jīng)包含了一些數(shù)據(jù),這些數(shù)據(jù)將會丟失。考慮這個例子:
$ echo line 1 > users $ cat users line 1 $您可以使用>>運算符將輸出附加在現(xiàn)有的文件如下:
$ echo line 2 >> users $ cat users line 1 line 2 $輸入重定向:
正如一個命令的輸出可以被重定向到一個文件中,所以可以輸入一個命令從文件重定向。作為不是字符>用于輸出重定向,小于字符<用于重定向一個命令的輸入。
通常需要的命令,他們從標準輸入的輸入可以有自己的這種方式從文件輸入重定向。例如,上面生成的文件中的用戶的數(shù)量來計算的行,可以執(zhí)行如下命令:
$ wc -l users 2 users $在這里,它產(chǎn)生的輸出2行。可以指望的文件中的行數(shù) wc 命令的標準輸入重定向用戶從文件:
$ wc -l < users 2 $請注意,在由兩種形式的wc命令產(chǎn)生的輸出是有區(qū)別的。在第一種情況下,該文件的用戶的名稱列出的行數(shù),在第二種情況下,它不是。
在第一種情況下,wc 知道,它是用戶從文件讀取輸入。在第二種情況下,只知道它是從標準輸入讀取輸入,所以它不顯示文件名。
Here 文檔:
?here document?是用來輸入重定向到一個交互式shell腳本或程序。
在一個shell腳本中,我們可以運行一個交互式程序,無需用戶操作,通過提供互動程序或交互式shell腳本所需的輸入。
這里的文件的一般形式是:
command << delimiter document delimiter這里的 shell 解釋<<操作指令讀取輸入,直到它找到含有指定分隔符線。所有輸入行的行分隔符,然后送入標準輸入的命令。
分界符告訴shell?這里文件已完成。沒有它,shell?不斷的讀取輸入。分隔符必須是一個字不包含空格或制表符。
以下是輸入命令wc -1 進行計數(shù)的行的總數(shù):
$wc -l << EOF ????????? This is a simple lookup program ????????? for good (and bad) restaurants ????????? in Cape Town. EOF 3 $可以在heredocument?打印多行,使用你的腳本如下:
#!/bin/sh ? cat << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town. EOF??????這將產(chǎn)生以下結果:
This is a simple lookup program for good (and bad) restaurants in Cape Town.下面的腳本運行一個會話vi文本編輯器中的輸入和保存文件test.txt。
#!/bin/sh ? filename=test.txt vi $filename <<EndOfCommands i This file was created automatically from a shell script ^[ ZZ EndOfCommands如果運行這個腳本,用vim作為vi,那么很可能會看到類似以下的輸出:
$ sh test.sh Vim: Warning: Input is not from a terminal $運行該腳本后,你應該看到以下內(nèi)容添加到文件test.txt:
$ cat test.txt This file was created automatically from a shell script $丟棄輸出:
有時會需要執(zhí)行命令,但不想顯示在屏幕上的輸出。在這種情況下,可以丟棄的輸出重定向到文件 /dev/null:
$ command > /dev/null這里 command 是要執(zhí)行的命令的名字。文件/dev/null?是一個特殊的文件自動放棄其所有的輸入。
同時要放棄一個命令的輸出和錯誤輸出,使用標準的重定向到STDOUT 到STDERR重定向:
$ command > /dev/null 2>&1在這里,2代表stderr和1代表STDOUT。可以上顯示一條消息到STDERR到 STDERR重定向標準輸入到如下:
$ echo message 1>&2重定向命令:
以下是命令,可以使用重定向的完整列表:
| 命令 | 描述 |
| pgm > file | Output of pgm is redirected to file |
| pgm < file | Program pgm reads its input from file. |
| pgm >> file | Output of pgm is appended to file. |
| n > file | Output from stream with descriptor n redirected to file. |
| n >> file | Output from stream with descriptor n appended to file. |
| n >& m | Merge output from stream n with stream m. |
| n <& m | Merge input from stream n with stream m. |
| << tag | Standard input comes from here through next tag at start of line. |
| | | Takes output from one program, or process, and sends it to another. |
需要注意的是文件描述符0是正常標準輸入(STDIN),1是標準輸出(STDOUT),標準錯誤輸出(STDERR)。
from: http://www.yiibai.com/shell/what_is_shell.html#
總結
以上是生活随笔為你收集整理的Shell教程(五):替代、引用机制、输入输出重定向的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell教程(四):条件语句、循环语句
- 下一篇: Shell教程(六):函数、联机帮助