亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
打印 上一主題 下一主題

[學(xué)習(xí)共享] shell 十三問(wèn)? [復(fù)制鏈接]

論壇徽章:
1
榮譽(yù)版主
日期:2011-11-23 16:44:17
61 [報(bào)告]
發(fā)表于 2004-01-13 03:37 |只看該作者

shell 十三問(wèn)?

8) $(( )) 與 $( ) 還有${ } 差在哪?

我們上一章介紹了 ( ) 與 { } 的不同,這次讓我們擴(kuò)展一下,看看更多的變化:$( ) 與 ${ } 又是啥玩意兒呢?

在 bash shell 中,$( ) 與 ` ` (反引號(hào)) 都是用來(lái)做命令替換用(command substitution)的。
所謂的命令替換與我們第五章學(xué)過(guò)的變量替換差不多,都是用來(lái)重組命令行:
* 完成引號(hào)裡的命令行,然後將其結(jié)果替換出來(lái),再重組命令行。
例如:
  1. $ echo the last sunday is $(date -d "last sunday" +%Y-%m-%d)
復(fù)制代碼

如此便可方便得到上一星期天的日期了... ^_^

在操作上,用 $( ) 或 ` ` 都無(wú)所謂,只是我"個(gè)人"比較喜歡用 $( ) ,理由是:

1,  ` ` 很容易與 ' ' ( 單引號(hào))搞混亂,尤其對(duì)初學(xué)者來(lái)說(shuō)。
有時(shí)在一些奇怪的字形顯示中,兩種符號(hào)是一模一樣的(直豎兩點(diǎn))。
當(dāng)然了,有經(jīng)驗(yàn)的朋友還是一眼就能分辯兩者。只是,若能更好的避免混亂,又何樂(lè)不為呢? ^_^

2, 在多層次的復(fù)合替換中,` ` 須要額外的跳脫( \` )處理,而 $( ) 則比較直觀。例如:
這是錯(cuò)的:
  1. command1 `command2 `command3` `
復(fù)制代碼

原本的意圖是要在 command2 `command3` 先將 command3 提換出來(lái)給 command 2 處理,
然後再將結(jié)果傳給 command1 `command2 ...` 來(lái)處理。
然而,真正的結(jié)果在命令行中卻是分成了 `command2 ` 與 `` 兩段。
正確的輸入應(yīng)該如下:
  1. command1 `command2 \`command3\` `
復(fù)制代碼


要不然,換成 $( ) 就沒(méi)問(wèn)題了:
  1. command1 $(command2 $(command3))
復(fù)制代碼

只要你喜歡,做多少層的替換都沒(méi)問(wèn)題啦~~~  ^_^

不過(guò),$( ) 並不是沒(méi)有斃端的...
首先,` ` 基本上可用在全部的 unix shell 中使用,若寫成 shell script ,其移植性比較高。
而 $( ) 並不見(jiàn)的每一種 shell 都能使用,我只能跟你說(shuō),若你用 bash2 的話,肯定沒(méi)問(wèn)題...  ^_^

接下來(lái),再讓我們看 ${ } 吧... 它其實(shí)就是用來(lái)作變量替換用的啦。
一般情況下,$var 與 ${var} 並沒(méi)有啥不一樣。
但是用 ${ } 會(huì)比較精確的界定變量名稱的範(fàn)圍,比方說(shuō):
  1. $ A=B
  2. $ echo $AB

復(fù)制代碼

原本是打算先將 $A 的結(jié)果替換出來(lái),然後再補(bǔ)一個(gè) B 字母於其後,
但在命令行上,真正的結(jié)果卻是只會(huì)提換變量名稱為 AB 的值出來(lái)...
若使用 ${ } 就沒(méi)問(wèn)題了:
  1. $ echo ${A}B
  2. BB
復(fù)制代碼


不過(guò),假如你只看到 ${ } 只能用來(lái)界定變量名稱的話,那你就實(shí)在太小看 bash 了﹗
有興趣的話,你可先參考一下 cu 本版的精華文章:
http://www.chinaunix.net/forum/viewtopic.php?t=201843

為了完整起見(jiàn),我這裡再用一些例子加以說(shuō)明 ${ } 的一些特異功能:
假設(shè)我們定義了一個(gè)變量為:
file=/dir1/dir2/dir3/my.file.txt
我們可以用 ${ } 分別替換獲得不同的值:
${file#*/}:拿掉第一條 / 及其左邊的字串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最後一條 / 及其左邊的字串:my.file.txt
${file#*.}:拿掉第一個(gè) .  及其左邊的字串:file.txt
${file##*.}:拿掉最後一個(gè) .  及其左邊的字串:txt
${file%/*}:拿掉最後條 / 及其右邊的字串:/dir1/dir2/dir3
${file%%/*}:拿掉第一條 / 及其右邊的字串:(空值)
${file%.*}:拿掉最後一個(gè) .  及其右邊的字串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一個(gè) .  及其右邊的字串:/dir1/dir2/dir3/my
記憶的方法為:
    # 是去掉左邊(在鑑盤上 # 在 $ 之左邊)
    % 是去掉右邊(在鑑盤上 % 在 $ 之右邊)
    單一符號(hào)是最小匹配﹔兩個(gè)符號(hào)是最大匹配。

${file:0:5}:提取最左邊的 5 個(gè)字節(jié):/dir1
${file:5:5}:提取第 5 個(gè)字節(jié)右邊的連續(xù) 5 個(gè)字節(jié):/dir2

我們也可以對(duì)變量值裡的字串作替換:
${file/dir/path}:將第一個(gè) dir 提換為 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:將全部 dir 提換為 path:/path1/path2/path3/my.file.txt

利用 ${ } 還可針對(duì)不同的變數(shù)狀態(tài)賦值(沒(méi)設(shè)定、空值、非空值):
${file-my.file.txt} :假如 $file 沒(méi)有設(shè)定,則使用 my.file.txt 作傳回值。(空值及非空值時(shí)不作處理)
${file:-my.file.txt} :假如 $file 沒(méi)有設(shè)定或?yàn)榭罩,則使用 my.file.txt 作傳回值。 (非空值時(shí)不作處理)
${file+my.file.txt} :假如 $file 設(shè)為空值或非空值,均使用 my.file.txt 作傳回值。(沒(méi)設(shè)定時(shí)不作處理)
${file:+my.file.txt} :若 $file 為非空值,則使用 my.file.txt 作傳回值。 (沒(méi)設(shè)定及空值時(shí)不作處理)
${file=my.file.txt} :若 $file 沒(méi)設(shè)定,則使用 my.file.txt 作傳回值,同時(shí)將 $file 賦值為 my.file.txt 。 (空值及非空值時(shí)不作處理)
${file:=my.file.txt} :若 $file 沒(méi)設(shè)定或?yàn)榭罩,則使用 my.file.txt 作傳回值,同時(shí)將 $file 賦值為 my.file.txt 。 (非空值時(shí)不作處理)
${file?my.file.txt} :若 $file 沒(méi)設(shè)定,則將 my.file.txt 輸出至 STDERR。 (空值及非空值時(shí)不作處理)
${file:?my.file.txt} :若 $file 沒(méi)設(shè)定或?yàn)榭罩担瑒t將 my.file.txt 輸出至 STDERR。 (非空值時(shí)不作處理)

tips:
以上的理解在於, 你一定要分清楚 unset 與 null 及 non-null 這三種賦值狀態(tài).
一般而言, : 與 null 有關(guān), 若不帶 : 的話, null 不受影響, 若帶 : 則連 null 也受影響.


還有哦,${#var} 可計(jì)算出變量值的長(zhǎng)度:
${#file} 可得到 27 ,因?yàn)?/dir1/dir2/dir3/my.file.txt 剛好是 27 個(gè)字節(jié)...

接下來(lái),再為大家介稍一下 bash 的組數(shù)(array)處理方法。
一般而言,A="a b c def" 這樣的變量只是將 $A 替換為一個(gè)單一的字串,
但是改為 A=(a b c def) ,則是將 $A 定義為組數(shù)...
bash 的組數(shù)替換方法可參考如下方法:
  1. ${A[@]} 或 ${A[*]}
復(fù)制代碼
可得到 a b c def (全部組數(shù))
  1. ${A[0]}
復(fù)制代碼
可得到 a (第一個(gè)組數(shù)),${A[1]} 則為第二個(gè)組數(shù)...
  1. ${#A[@]} 或 ${#A[*]}  
復(fù)制代碼
可得到 4 (全部組數(shù)數(shù)量)
  1. ${#A[0]}
復(fù)制代碼
可得到 1 (即第一個(gè)組數(shù)(a)的長(zhǎng)度),${#A[3]} 可得到 3 (第四個(gè)組數(shù)(def)的長(zhǎng)度)
  1. A[3]=xyz  
復(fù)制代碼
則是將第四個(gè)組數(shù)重新定義為 xyz ...

諸如此類的....
能夠善用 bash 的 $( ) 與 ${ } 可大大提高及簡(jiǎn)化 shell 在變量上的處理能力哦~~~  ^_^

好了,最後為大家介紹 $(( )) 的用途吧:它是用來(lái)作整數(shù)運(yùn)算的。
在 bash 中,$(( )) 的整數(shù)運(yùn)算符號(hào)大致有這些:
+ - * / :分別為 "加、減、乘、除"。
% :餘數(shù)運(yùn)算
& | ^ !:分別為 "AND、OR、XOR、NOT" 運(yùn)算。

例:
  1. $ a=5; b=7; c=2
  2. $ echo $(( a+b*c ))
  3. 19
  4. $ echo $(( (a+b)/c ))
  5. 6
  6. $ echo $(( (a*b)%c))
  7. 1
復(fù)制代碼


在 $(( )) 中的變量名稱,可於其前面加 $ 符號(hào)來(lái)替換,也可以不用,如:
$(( $a + $b * $c)) 也可得到 19 的結(jié)果

此外,$(( )) 還可作不同進(jìn)位(如二進(jìn)位、八進(jìn)位、十六進(jìn)位)作運(yùn)算呢,只是,輸出結(jié)果皆為十進(jìn)位而已:
echo $((16#2a)) 結(jié)果為 42 (16進(jìn)位轉(zhuǎn)十進(jìn)位)
以一個(gè)實(shí)用的例子來(lái)看看吧:
假如當(dāng)前的  umask 是 022 ,那麼新建文件的權(quán)限即為:
  1. $ umask 022
  2. $ echo "obase=8;$(( 8#666 & (8#777 ^ 8#$(umask)) ))" | bc
  3. 644
復(fù)制代碼


事實(shí)上,單純用 (( )) 也可重定義變量值,或作 testing:
a=5; ((a++)) 可將 $a 重定義為 6
a=5; ((a--)) 則為 a=4
a=5; b=7; ((a < b)) 會(huì)得到  0 (true) 的返回值。
常見(jiàn)的用於 (( )) 的測(cè)試符號(hào)有如下這些:
    <:小於
    >:大於
    <=:小於或等於
    >=:大於或等於
    ==:等於
    !=:不等於

不過(guò),使用 (( )) 作整數(shù)測(cè)試時(shí),請(qǐng)不要跟 [ ] 的整數(shù)測(cè)試搞混亂了。(更多的測(cè)試我將於第十章為大家介紹)

怎樣?好玩吧..  ^_^  okay,這次暫時(shí)說(shuō)這麼多...
上面的介紹,並沒(méi)有詳列每一種可用的狀態(tài),更多的,就請(qǐng)讀者參考手冊(cè)文件囉...

[ 本帖最后由 網(wǎng)中人 于 2008-12-3 02:39 編輯 ]

論壇徽章:
0
62 [報(bào)告]
發(fā)表于 2004-01-13 17:09 |只看該作者

shell 十三問(wèn)?

好久沒(méi)來(lái),各位公歷日見(jiàn)深厚,佩服,慚愧。
頂一把。

論壇徽章:
0
63 [報(bào)告]
發(fā)表于 2004-01-14 16:50 |只看該作者

shell 十三問(wèn)?

好人啊,支持

論壇徽章:
0
64 [報(bào)告]
發(fā)表于 2004-01-14 19:42 |只看該作者

shell 十三問(wèn)?

好貼,請(qǐng)繼續(xù)。。。

論壇徽章:
1
榮譽(yù)版主
日期:2011-11-23 16:44:17
65 [報(bào)告]
發(fā)表于 2004-01-15 02:22 |只看該作者

shell 十三問(wèn)?

9) $@ 與 $* 差在哪?

要說(shuō) $@ 與 $* 之前,需得先從 shell script 的 positional parameter 談起...
我們都已經(jīng)知道變量(variable)是如何定義及替換的,這個(gè)不用再多講了。
但是,我們還需要知道有些變量是 shell 內(nèi)定的,且其名稱是我們不能隨意修改的,
其中就有 positional parameter 在內(nèi)。

在 shell script 中,我們可用 $0, $1, $2, $3 ... 這樣的變量分別提取命令行中的如下部份:
  1. script_name parameter1 parameter2 parameter3 ...
復(fù)制代碼

我們很容易就能猜出 $0 就是代表 shell script 名稱(路逕)本身,而 $1 就是其後的第一個(gè)參數(shù),如此類推....
須得留意的是 IFS 的作用,也就是,若 IFS 被 quoting 處理後,那麼 positional parameter 也會(huì)改變。
如下例:
  1. my.sh p1 "p2 p3" p4
復(fù)制代碼

由於在 p2 與 p3 之間的空白鍵被 soft quote 所關(guān)閉了,因此 my.sh 中的 $2 是 "p2 p3" 而 $3 則是 p4 ...

還記得前兩章我們提到 fucntion 時(shí),我不是說(shuō)過(guò)它是 script 中的 script 嗎?  ^_^
是的,function 一樣可以讀取自己的(有別於 script 的) postitional parameter ,惟一例外的是 $0 而已。
舉例而言:假設(shè) my.sh 裡有一個(gè) fucntion 叫 my_fun , 若在 script 中跑 my_fun fp1 fp2 fp3 ,
那麼,function 內(nèi)的 $0 是 my.sh ,而 $1 則是 fp1 而非 p1 了...

不如寫個(gè)簡(jiǎn)單的 my.sh script  看看吧:
  1. #!/bin/bash

  2. my_fun() {
  3.     echo '$0 inside function is '$0
  4.     echo '$1 inside function is '$1
  5.     echo '$2 inside function is '$2
  6. }

  7. echo '$0 outside function is '$0
  8. echo '$1 outside function is '$1
  9. echo '$2 outside function is '$2

  10. my_fun fp1 "fp2 fp3"
復(fù)制代碼

然後在 command line 中跑一下 script 就知道了:
  1. chmod +x my.sh
  2. ./my.sh p1 "p2 p3"
  3. $0 outside function is ./my.sh
  4. $1 outside function is p1
  5. $2 outside function is p2 p3
  6. $0 inside function is ./my.sh
  7. $1 inside function is fp1
  8. $2 inside function is fp2 fp3
復(fù)制代碼


然而,在使用 positional parameter 的時(shí)候,我們要注意一些陷阱哦:
* $10 不是替換第 10 個(gè)參數(shù),而是替換第一個(gè)參數(shù)($1)然後再補(bǔ)一個(gè) 0 於其後﹗
也就是,my.sh one two three four five six seven eigth nine ten 這樣的 command line ,
my.sh 裡的 $10 不是 ten 而是 one0 哦... 小心小心﹗
要抓到 ten 的話,有兩種方法:

方法一是使用我們上一章介紹的 ${ } ,也就是用 ${10} 即可。

方法二,就是 shift 了。
用通俗的說(shuō)法來(lái)說(shuō),所謂的 shift 就是取消 positional parameter 中最左邊的參數(shù)( $0 不受影響)。
其預(yù)設(shè)值為 1 ,也就是 shift 或 shift 1  都是取消 $1 ,而原本的 $2 則變成 $1、$3 變成 $2 ...
若 shift 3 則是取消前面三個(gè)參數(shù),也就是原本的 $4 將變成 $1 ...
那,親愛(ài)的讀者,你說(shuō)要 shift 掉多少個(gè)參數(shù),才可用 $1 取得 ${10} 呢? ^_^

okay,當(dāng)我們對(duì) positional parameter 有了基本概念之後,那再讓我們看看其他相關(guān)變量吧。
首先是 $# :它可抓出 positional parameter 的數(shù)量。
以前面的 my.sh p1 "p2 p3" 為例:
由於 p2 與 p3 之間的 IFS 是在 soft quote 中,因此 $# 可得到 2 的值。
但如果 p2 與 p3 沒(méi)有置於 quoting 中話,那 $# 就可得到 3 的值了。
同樣的道理在 function 中也是一樣的...

因此,我們常在 shell script 裡用如下方法測(cè)試 script 是否有讀進(jìn)參數(shù):
  1. [ $# = 0 ]
復(fù)制代碼

假如為 0 ,那就表示 script 沒(méi)有參數(shù),否則就是有帶參數(shù)...

接下來(lái)就是 $@ 與 $* :
精確來(lái)講,兩者只有在 soft quote 中才有差異,否則,都表示"全部參數(shù)"( $0 除外)。
舉例來(lái)說(shuō)好了:
若在 command line 上跑 my.sh p1 "p2 p3" p4 的話,
不管是 $@ 還是 $* ,都可得到 p1 p2 p3 p4 就是了。
但是,如果置於 soft quote 中的話:
"$@" 則可得到 "p1" "p2 p3" "p4" 這三個(gè)不同的詞段(word)﹔
"$*" 則可得到 "p1 p2 p3 p4" 這一整串單一的詞段。

我們可修改一下前面的 my.sh ,使之內(nèi)容如下:
  1. #!/bin/bash

  2. my_fun() {
  3.     echo "$#"
  4. }

  5. echo 'the number of parameter in "$@" is '$(my_fun "$@")
  6. echo 'the number of parameter in "$*" is '$(my_fun "$*")
復(fù)制代碼


然後再執(zhí)行 ./my.sh p1 "p2 p3" p4 就知道 $@ 與 $* 差在哪了 ...    ^_^

論壇徽章:
1
榮譽(yù)版主
日期:2011-11-23 16:44:17
66 [報(bào)告]
發(fā)表于 2004-01-16 03:48 |只看該作者

shell 十三問(wèn)?

10) && 與 || 差在哪?

好不容易,進(jìn)入兩位數(shù)的章節(jié)了... 一路走來(lái),很辛苦吧?也很快樂(lè)吧?  ^_^

在解答本章題目之前,先讓我們了解一個(gè)概念:return value ﹗
我們?cè)?shell 下跑的每一個(gè) command 或 function ,在結(jié)束的時(shí)候都會(huì)傳回父行程一個(gè)值,稱為 return value 。
在 shell command line 中可用 $? 這個(gè)變量得到最"新"的一個(gè) return value ,也就是剛結(jié)束的那個(gè)行程傳回的值。
Return Value(RV) 的取值為 0-255 之間,由程式(或 script)的作者自行定議:
* 若在 script 裡,用 exit RV 來(lái)指定其值,若沒(méi)指定,在結(jié)束時(shí)以最後一道命令之 RV 為值。
* 若在 function 裡,則用 return RV 來(lái)代替 exit RV 即可。

Return Value 的作用,是用來(lái)判斷行程的退出狀態(tài)(exit status),只有兩種:
* 0 的話為"真"( true )
* 非  0 的話為"假"( false )

舉個(gè)例子來(lái)說(shuō)明好了:
假設(shè)當(dāng)前目錄內(nèi)有一份 my.file 的文件,而 no.file 是不存在的:
  1. $ touch my.file
  2. $ ls my.file
  3. $ echo $?        # first echo
  4. 0
  5. $ ls no.file
  6. ls: no.file: No such file or directory
  7. $ echo $?        # second echo
  8. 1
  9. $ echo $?        # third echo
  10. 0
復(fù)制代碼

上例的第一個(gè) echo 是關(guān)於 ls my.file 的 RV ,可得到 0 的值,因此為 true ﹔
第二個(gè) echo 是關(guān)於 ls no.file 的 RV ,則得到非 0  的值,因此為 false ﹔
第三個(gè) echo 是關(guān)於第二個(gè) echo $? 的 RV ,為 0 的值,因此也為 true 。

請(qǐng)記。好恳粋(gè) command 在結(jié)束時(shí)都會(huì)送回 return value 的﹗不管你跑甚麼樣的命令...
然而,有一個(gè)命令卻是"專門"用來(lái)測(cè)試某一條件而送出 return value 以供 true 或 false 的判斷,
它就是 test 命令了﹗
若你用的是 bash ,請(qǐng)?jiān)?command line 下打 man test 或 man bash 來(lái)了解這個(gè) test 的用法。
這是你可用作參考的最精確的文件了,要是聽別人說(shuō)的,僅作參考就好...
下面我只簡(jiǎn)單作一些輔助說(shuō)明,其餘的一律以 man 為準(zhǔn):

首先,test 的表示式我們稱為 expression ,其命令格式有兩種:
  1. test expression
  2. or:
  3. [ expression ]
復(fù)制代碼

(請(qǐng)務(wù)必注意 [ ] 之間的空白鍵﹗)
用哪一種格式?jīng)]所謂,都是一樣的效果。(我個(gè)人比較喜歡後者...)

其次,bash 的 test 目前支援的測(cè)試對(duì)像只有三種:
* string:字串,也就是純文字。
* integer:整數(shù)( 0 或正整數(shù),不含負(fù)數(shù)或小數(shù)點(diǎn))。
* file:文件。
請(qǐng)初學(xué)者一定要搞清楚這三者的差異,因?yàn)?test 所用的 expression 是不一樣的。
以 A=123 這個(gè)變量為例:
* [ "$A" = 123 ]:是字串的測(cè)試,以測(cè)試 $A 是否為 1、2、3 這三個(gè)連續(xù)的"文字"。
* [ "$A" -eq 123 ]:是整數(shù)的測(cè)試,以測(cè)試 $A 是否等於"一百二十三"。
* [ -e "$A" ]:是關(guān)於文件的測(cè)試,以測(cè)試 123 這份"文件"是否存在。

第三,當(dāng) expression 測(cè)試為"真"時(shí),test 就送回 0 (true) 的 return value ,否則送出非 0 (false)。
若在 expression 之前加上一個(gè) " ! "(感嘆號(hào)),則是當(dāng) expression 為"假時(shí)" 才送出 0 ,否則送出非 0 。
同時(shí),test 也允許多重的覆合測(cè)試:
* expression1 -a expression2 :當(dāng)兩個(gè) exrepssion 都為 true ,才送出 0 ,否則送出非 0 。
* expression1 -o expression2 :只需其中一個(gè) exrepssion 為 true ,就送出 0 ,只有兩者都為 false 才送出非 0 。
例如:
  1. [ -d "$file" -a -x "$file" ]
復(fù)制代碼

是表示當(dāng) $file 是一個(gè)目錄、且同時(shí)具有 x 權(quán)限時(shí),test 才會(huì)為 true 。

第四,在 command line 中使用 test 時(shí),請(qǐng)別忘記命令行的"重組"特性,
也就是在碰到 meta 時(shí)會(huì)先處理 meta 再重新組建命令行。(這個(gè)特性我在第二及第四章都曾反覆強(qiáng)調(diào)過(guò))
比方說(shuō),若 test 碰到變量或命令替換時(shí),若不能滿足 expression 格式時(shí),將會(huì)得到語(yǔ)法錯(cuò)誤的結(jié)果。
舉例來(lái)說(shuō)好了:
關(guān)於 [ string1 = string2 ] 這個(gè) test 格式,
在 = 號(hào)兩邊必須要有字串,其中包括空(null)字串(可用 soft quote  或 hard quote 取得)。
假如 $A 目前沒(méi)有定義,或被定議為空字串的話,那如下的寫法將會(huì)失。
  1. $ unset A
  2. $ [ $A = abc ]
  3. [: =: unary operator expected
復(fù)制代碼

這是因?yàn)槊钚信龅?nbsp; $ 這個(gè) meta 時(shí),會(huì)替換 $A 的值,然後再重組命令行,那就變成了:
[ = abc ]
如此一來(lái) = 號(hào)左邊就沒(méi)有字串存在了,因此造成 test 的語(yǔ)法錯(cuò)誤﹗
但是,下面這個(gè)寫法則是成立的:
  1. $ [ "$A" = abc ]
  2. $ echo $?
  3. 1
復(fù)制代碼

這是因?yàn)樵诿钚兄亟M後的結(jié)果為:
[ "" = abc ]
由於 = 左邊我們用 soft quote 得到一個(gè)空字串,而讓 test 語(yǔ)法得以通過(guò)...

讀者諸君請(qǐng)務(wù)必留意這些細(xì)節(jié)哦,因?yàn)樯砸徊簧鳎瑢?huì)導(dǎo)至 test 的結(jié)果變了個(gè)樣﹗
若您對(duì) test 還不是很有經(jīng)驗(yàn)的話,那在使用 test 時(shí)不妨先採(cǎi)用如下這一個(gè)"法則":
* 假如在 test 中碰到變量替換,用 soft quote 是最保險(xiǎn)的﹗
若你對(duì) quoting 不熟的話,請(qǐng)重新溫習(xí)第四章的內(nèi)容吧...  ^_^

okay,關(guān)於更多的 test 用法,老話一句:請(qǐng)看 man page 吧﹗  ^_^

雖然洋洋灑灑講了一大堆,或許你還在嘀咕.... 那... 那個(gè) return value 有啥用?﹗
問(wèn)得好﹗
告訴你:return value 的作用可大了﹗若你想讓你的 shell 變"聰明"的話,就全靠它了:
* 有了 return value,我們可以讓 shell 跟據(jù)不同的狀態(tài)做不同的時(shí)情...

這時(shí)候,才讓我來(lái)揭曉本章的答案吧~~~  ^_^
&& 與 || 都是用來(lái)"組建"多個(gè) command line 用的:
* command1 && command2 :其意思是 command2 只有在 RV 為 0 (true) 的條件下執(zhí)行。
* command1 || command2 :其意思是 command2 只有在 RV 為非 0 (false) 的條件下執(zhí)行。
來(lái),以例子來(lái)說(shuō)好了:
  1. $ A=123
  2. $ [ -n "$A" ] && echo "yes! it's ture."
  3. yes! it's ture.
  4. $ unset A
  5. $ [ -n "$A" ] && echo "yes! it's ture."
  6. $ [ -n "$A" ] || echo "no, it's NOT ture."
  7. no, it's NOT ture.
復(fù)制代碼

(註:[ -n string ] 是測(cè)試 string 長(zhǎng)度大於 0 則為 true 。)
上例的第一個(gè) && 命令行之所以會(huì)執(zhí)行其右邊的 echo 命令,是因?yàn)樯弦粋(gè) test 送回了 0 的 RV 值﹔
但第二次就不會(huì)執(zhí)行,因?yàn)?test 送回非 0 的結(jié)果...
同理,|| 右邊的 echo 會(huì)被執(zhí)行,卻正是因?yàn)樽筮叺?test 送回非 0 所引起的。

事實(shí)上,我們?cè)谕幻钚兄校捎枚鄠(gè) && 或 || 來(lái)組建呢:
  1. $ A=123
  2. $ [ -n "$A" ] && echo "yes! it's ture." || echo "no, it's NOT ture."
  3. yes! it's ture.
  4. $ unset A
  5. $ [ -n "$A" ] && echo "yes! it's ture." || echo "no, it's NOT ture."
  6. no, it's NOT ture.
復(fù)制代碼

怎樣,從這一刻開始,你是否覺(jué)得我們的 shell 是"很聰明"的呢?  ^_^

好了,最後,佈置一道習(xí)題給大家做做看、、、
下面的判斷是:當(dāng) $A 被賦與值時(shí),再看是否小於 100 ,否則送出 too big! :
  1. $ A=123
  2. $ [ -n "$A" ] && [ "$A" -lt 100 ] || echo 'too big!'
  3. too big!
復(fù)制代碼

若我將 A 取消,照理說(shuō),應(yīng)該不會(huì)送文字才對(duì)啊(因?yàn)榈谝粋(gè)條件就不成立了)...
  1. $ unset A
  2. $ [ -n "$A" ] && [ "$A" -lt 100 ] || echo 'too big!'
  3. too big!
復(fù)制代碼

為何上面的結(jié)果也可得到呢?
又,如何解決之呢?
(提示:修改方法很多,其中一種方法可利用第七章介紹過(guò)的 command group ...)

快﹗告我我答案﹗其餘免談....

[ 本帖最后由 網(wǎng)中人 于 2008-10-30 02:21 編輯 ]

論壇徽章:
1
榮譽(yù)版主
日期:2011-11-23 16:44:17
67 [報(bào)告]
發(fā)表于 2004-01-16 14:44 |只看該作者

shell 十三問(wèn)?

11) > 與 < 差在哪?

這次的題目之前我在 CU 的 shell 版已說(shuō)明過(guò)了:
(原貼連結(jié)在論壇改版後已經(jīng)失效)
這次我就不重寫了,將貼子的內(nèi)容"抄"下來(lái)就是了...

--------------
11.1
談到 I/O redirection ,不妨先讓我們認(rèn)識(shí)一下 File Descriptor (FD) 。

程式的運(yùn)算,在大部份情況下都是進(jìn)行數(shù)據(jù)(data)的處理,
這些數(shù)據(jù)從哪讀進(jìn)?又,送出到哪裡呢?
這就是 file descriptor (FD) 的功用了。

在 shell 程式中,最常使用的 FD 大概有三個(gè),分別為:
0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)

在標(biāo)準(zhǔn)情況下,這些 FD 分別跟如下設(shè)備(device)關(guān)聯(lián):
stdin(0): keyboard
stdout(1): monitor
stderr(2): monitor

我們可以用如下下命令測(cè)試一下:
  1. $ mail -s test root
  2. this is a test mail.
  3. please skip.
  4. ^d (同時(shí)按 crtl 跟 d 鍵)
復(fù)制代碼

很明顯,mail 程式所讀進(jìn)的數(shù)據(jù),就是從 stdin 也就是 keyboard 讀進(jìn)的。
不過(guò),不見(jiàn)得每個(gè)程式的 stdin 都跟 mail 一樣從 keyboard 讀進(jìn),
因?yàn)槌淌阶髡呖梢詮臋n案參數(shù)讀進(jìn) stdin ,如:
  1. $ cat /etc/passwd
復(fù)制代碼

但,要是 cat 之後沒(méi)有檔案參數(shù)則又如何呢?
哦,請(qǐng)您自己玩玩看囉.... ^_^
  1. $ cat
復(fù)制代碼


(請(qǐng)留意數(shù)據(jù)輸出到哪裡去了,最後別忘了按 ^d 離開...)

至於 stdout 與 stderr ,嗯... 等我有空再續(xù)吧... ^_^
還是,有哪位前輩要來(lái)玩接龍呢?

--------------
11.2
沿文再續(xù),書接上一回... ^_^

相信,經(jīng)過(guò)上一個(gè)練習(xí)後,你對(duì) stdin 與 stdout 應(yīng)該不難理解吧?
然後,讓我們繼續(xù)看 stderr 好了。
事實(shí)上,stderr 沒(méi)甚麼難理解的:說(shuō)穿了就是"錯(cuò)誤信息"要往哪邊送而已...
比方說(shuō),若讀進(jìn)的檔案參數(shù)是不存在的,那我們?cè)?monitor 上就看到了:
  1. $ ls no.such.file
  2. ls: no.such.file: No such file or directory
復(fù)制代碼


若,一個(gè)命令同時(shí)產(chǎn)生 stdout 與 stderr 呢?
那還不簡(jiǎn)單,都送到 monitor 來(lái)就好了:
  1. $ touch my.file
  2. $ ls my.file no.such.file
  3. ls: no.such.file: No such file or directory
  4. my.file
復(fù)制代碼


okay,至此,關(guān)於 FD 及其名稱、還有相關(guān)聯(lián)的設(shè)備,相信你已經(jīng)沒(méi)問(wèn)題了吧?
那好,接下來(lái)讓我們看看如何改變這些 FD 的預(yù)設(shè)數(shù)據(jù)通道,
我們可用 < 來(lái)改變讀進(jìn)的數(shù)據(jù)通道(stdin),使之從指定的檔案讀進(jìn)。
我們可用 > 來(lái)改變送出的數(shù)據(jù)通道(stdout, stderr),使之輸出到指定的檔案。

比方說(shuō):
  1. $ cat < my.file
復(fù)制代碼

就是從 my.file 讀進(jìn)數(shù)據(jù)
  1. $ mail -s test root < /etc/passwd
復(fù)制代碼

則是從 /etc/passwd 讀進(jìn)...
這樣一來(lái),stdin 將不再是從 keyboard 讀進(jìn),而是從檔案讀進(jìn)了...
嚴(yán)格來(lái)說(shuō),< 符號(hào)之前需要指定一個(gè) FD 的(之間不能有空白),
但因?yàn)?0 是 < 的預(yù)設(shè)值,因此 < 與 0< 是一樣的﹗

okay,這個(gè)好理解吧?
那,要是用兩個(gè) << 又是啥呢?
這是所謂的 HERE Document ,它可以讓我們輸入一段文本,直到讀到 << 後指定的字串。
比方說(shuō):
  1. $ cat <<FINISH
  2. first line here
  3. second line there
  4. third line nowhere
  5. FINISH
復(fù)制代碼

這樣的話,cat 會(huì)讀進(jìn) 3 行句子,而無(wú)需從 keyboard 讀進(jìn)數(shù)據(jù)且要等 ^d 結(jié)束輸入。

至於 > 又如何呢?
且聽下回分解....

--------------
11.3
okay,又到講古時(shí)間~~~

當(dāng)你搞懂了 0< 原來(lái)就是改變 stdin 的數(shù)據(jù)輸入通道之後,相信要理解如下兩個(gè) redirection 就不難了:
* 1>
* 2>
前者是改變 stdout 的數(shù)據(jù)輸出通道,後者是改變 stderr 的數(shù)據(jù)輸出通道。
兩者都是將原本要送出到 monitor 的數(shù)據(jù)轉(zhuǎn)向輸出到指定檔案去。
由於 1 是 > 的預(yù)設(shè)值,因此,1> 與 > 是相同的,都是改變 stdout 。

用上次的 ls 例子來(lái)說(shuō)明一下好了:

  1. $ ls my.file no.such.file 1>file.out
  2. ls: no.such.file: No such file or directory
復(fù)制代碼

這樣 monitor 就只剩下 stderr 而已。因?yàn)?stdout 給寫進(jìn) file.out 去了。

  1. $ ls my.file no.such.file 2>file.err
  2. my.file
復(fù)制代碼

這樣 monitor 就只剩下 stdout ,因?yàn)?stderr 寫進(jìn)了 file.err 。

  1. $ ls my.file no.such.file 1>file.out 2>file.err
復(fù)制代碼

這樣 monitor 就啥也沒(méi)有,因?yàn)?stdout 與 stderr 都給轉(zhuǎn)到檔案去了...

呵~~~ 看來(lái)要理解 > 一點(diǎn)也不難啦﹗是不?沒(méi)騙你吧? ^_^
不過(guò),有些地方還是要注意一下的。

首先,是同時(shí)寫入的問(wèn)題。比方如下這個(gè)例子:

  1. $ ls my.file no.such.file 1>file.both 2>file.both
復(fù)制代碼

假如 stdout(1) 與 stderr(2) 都同時(shí)在寫入 file.both 的話,
則是採(cǎi)取“覆蓋”方式:後來(lái)寫入的覆蓋前面的。
讓我們假設(shè)一個(gè) stdout 與 stderr 同時(shí)寫入 file.out 的情形好了:
* 首先 stdout 寫入10個(gè)字元
* 然後 stderr 寫入 6 個(gè)字元
那麼,這時(shí)候原本 stdout 輸出的 10 個(gè)字元就被 stderr 覆蓋掉了。

那,如何解決呢?所謂山不轉(zhuǎn)路轉(zhuǎn)、路不轉(zhuǎn)人轉(zhuǎn)嘛,
我們可以換一個(gè)思維:將 stderr 導(dǎo)進(jìn) stdout 或?qū)?stdout 導(dǎo)進(jìn) sterr ,而不是大家在搶同一份檔案,不就行了﹗
bingo﹗就是這樣啦:
* 2>&1 就是將 stderr 併進(jìn) stdout 作輸出
* 1>&2 或 >&2 就是將 stdout 併進(jìn) stderr 作輸出
於是,前面的錯(cuò)誤操作可以改為:
  1. $ ls my.file no.such.file 1>file.both 2>&1

  2. $ ls my.file no.such.file 2>file.both >&2
復(fù)制代碼


這樣,不就皆大歡喜了嗎? 呵~~~ ^_^

不過(guò),光解決了同時(shí)寫入的問(wèn)題還不夠,我們還有其他技巧需要了解的。
故事還沒(méi)結(jié)束,別走開﹗廣告後,我們?cè)倩貋?lái)...﹗


--------------
11.4
okay,這次不講 I/O Redirction ,講佛吧...
(有沒(méi)搞錯(cuò)?﹗網(wǎng)中人是否頭殼燒壞了?...) 嘻~~~ ^_^

學(xué)佛的最高境界,就是"四大皆空"。至於是空哪四大塊?我也不知,因?yàn)槲疫沒(méi)到那境界...
但這個(gè)"空"字,卻非常值得我們返複把玩的:
--- 色即是空、空即是色﹗
好了,施主要是能夠領(lǐng)會(huì)"空"的禪意,那離修成正果不遠(yuǎn)矣~~~

在 Linux 檔案系統(tǒng)裡,有個(gè)設(shè)備檔位於 /dev/null 。
許多人都問(wèn)過(guò)我那是甚麼玩意兒?我跟你說(shuō)好了:那就是"空"啦﹗
沒(méi)錯(cuò)﹗空空如也的空就是 null 了.... 請(qǐng)問(wèn)施主是否忽然有所頓誤了呢?然則恭喜了~~~ ^_^

這個(gè) null 在 I/O Redirection 中可有用得很呢:
* 若將 FD1 跟 FD2 轉(zhuǎn)到 /dev/null 去,就可將 stdout 與 stderr 弄不見(jiàn)掉。
* 若將 FD0 接到 /dev/null 來(lái),那就是讀進(jìn) nothing 。
比方說(shuō),當(dāng)我們?cè)趫?zhí)行一個(gè)程式時(shí),畫面會(huì)同時(shí)送出 stdout 跟 stderr ,
假如你不想看到 stderr (也不想存到檔案去),那可以:
  1. $ ls my.file no.such.file 2>/dev/null
  2. my.file
復(fù)制代碼


若要相反:只想看到 stderr 呢?還不簡(jiǎn)單﹗將 stdout 弄到 null 就行:
  1. $ ls my.file no.such.file >/dev/null
  2. ls: no.such.file: No such file or directory
復(fù)制代碼


那接下來(lái),假如單純只跑程式,不想看到任何輸出結(jié)果呢?
哦,這裡留了一手上次節(jié)目沒(méi)講的法子,專門贈(zèng)予有緣人﹗... ^_^
除了用 >/dev/null 2>&1 之外,你還可以如此:
  1. $ ls my.file no.such.file &>/dev/null
復(fù)制代碼

(提示:將 &> 換成 >& 也行啦~~! )

okay?講完佛,接下來(lái),再讓我們看看如下情況:
  1. $ echo "1" > file.out
  2. $ cat file.out
  3. 1
  4. $ echo "2" > file.out
  5. $ cat file.out
  6. 2
復(fù)制代碼

看來(lái),我們?cè)谥貙?dǎo) stdout 或 stderr 進(jìn)一份檔案時(shí),似乎永遠(yuǎn)只獲得最後一次導(dǎo)入的結(jié)果。
那,之前的內(nèi)容呢?
呵~~~ 要解決這個(gè)問(wèn)提很簡(jiǎn)單啦,將 > 換成 >> 就好:
  1. $ echo "3" >> file.out
  2. $ cat file.out
  3. 2
  4. 3
復(fù)制代碼

如此一來(lái),被重導(dǎo)的目標(biāo)檔案之內(nèi)容並不會(huì)失去,而新的內(nèi)容則一直增加在最後面去。
easy ? 呵 ... ^_^

但,只要你再一次用回單一的 > 來(lái)重導(dǎo)的話,那麼,舊的內(nèi)容還是會(huì)被"洗"掉的﹗
這時(shí),你要如何避免呢?
----備份﹗ yes ,我聽到了﹗不過(guò).... 還有更好的嗎?
既然與施主這麼有緣份,老納就送你一個(gè)錦囊妙法吧:
  1. $ set -o noclobber
  2. $ echo "4" > file.out
  3. -bash: file: cannot overwrite existing file
復(fù)制代碼


那,要如何取消這個(gè)"限制"呢?
哦,將 set -o 換成 set +o 就行:
  1. $ set +o noclobber
  2. $ echo "5" > file.out
  3. $ cat file.out
  4. 5
復(fù)制代碼


再問(wèn):那... 有辦法不取消而又"臨時(shí)"蓋寫目標(biāo)檔案嗎?
哦,佛曰:不可告也﹗
啊~~~ 開玩笑的、開玩笑的啦~~~ ^_^ 唉,早就料到人心是不足的了﹗
  1. $ set -o noclobber
  2. $ echo "6" >| file.out
  3. $ cat file.out
  4. 6
復(fù)制代碼

留意到?jīng)]有:在 > 後面再加個(gè)" | "就好(注意: > 與 | 之間不能有空白哦)....

呼.... (深呼吸吐納一下吧)~~~ ^_^
再來(lái)還有一個(gè)難題要你去參透的呢:
  1. $ echo "some text here" > file
  2. $ cat < file
  3. some text here
  4. $ cat < file > file.bak
  5. $ cat < file.bak
  6. some text here
  7. $ cat < file > file
  8. $ cat < file
復(fù)制代碼


嗯?﹗注意到?jīng)]有?﹗﹗
---- 怎麼最後那個(gè) cat 命令看到的 file 竟是空的?﹗
why? why? why?

同學(xué)們:下節(jié)課不要遲到囉~~~!


--------------
11.5
噹噹噹~~~ 上課囉~~~ ^_^

前面提到:$ cat < file > file 之後原本有內(nèi)容的檔案結(jié)果卻被洗掉了﹗
要理解這一現(xiàn)像其實(shí)不難,這只是 priority 的問(wèn)題而已:
* 在 IO Redirection 中,stdout 與 stderr 的管道會(huì)先準(zhǔn)備好,才會(huì)從 stdin 讀進(jìn)資料。
也就是說(shuō),在上例中,> file 會(huì)先將 file 清空,然後才讀進(jìn) < file ,
但這時(shí)候檔案已經(jīng)被清空了,因此就變成讀不進(jìn)任何資料了...

哦~~~ 原來(lái)如此~~~~ ^_^
那... 如下兩例又如何呢?
  1. $ cat <> file
  2. $ cat < file >> file
復(fù)制代碼


嗯... 同學(xué)們,這兩個(gè)答案就當(dāng)練習(xí)題囉,下節(jié)課之前請(qǐng)交作業(yè)﹗

好了,I/O Redirection 也快講完了,sorry,因?yàn)槲乙仓恢肋@麼多而已啦~~~ 嘻~~ ^_^
不過(guò),還有一樣?xùn)|東是一定要講的,各位觀眾(請(qǐng)自行配樂(lè)~!#@!$%) :
---- 就是 pipe line 也﹗

談到 pipe line ,我相信不少人都不會(huì)陌生:
我們?cè)诤芏?command line 上?吹降" | "符號(hào)就是 pipe line 了。
不過(guò),究竟 pipe line 是甚麼東東呢?
別急別急... 先查一下英漢字典,看看 pipe 是甚麼意思?
沒(méi)錯(cuò)﹗它就是"水管"的意思...
那麼,你能想像一下水管是怎麼一根接著一根的嗎?
又,每根水管之間的 input 跟 output 又如何呢?
嗯??
靈光一閃:原來(lái) pipe line 的 I/O 跟水管的 I/O 是一模一樣的:
* 上一個(gè)命令的 stdout 接到下一個(gè)命令的 stdin 去了﹗
的確如此... 不管在 command line 上你使用了多少個(gè) pipe line ,
前後兩個(gè) command 的 I/O 都是彼此連接的﹗(恭喜:你終於開竅了﹗ ^_^ )

不過(guò)... 然而... 但是... ... stderr 呢?
好問(wèn)題﹗不過(guò)也容易理解:
* 若水管漏水怎麼辦?
也就是說(shuō):在 pipe line 之間,前一個(gè)命令的 stderr 是不會(huì)接進(jìn)下一命令的 stdin 的,
其輸出,若不用 2> 導(dǎo)到 file 去的話,它還是送到監(jiān)視器上面來(lái)﹗
這點(diǎn)請(qǐng)你在 pipe line 運(yùn)用上務(wù)必要注意的。

那,或許你又會(huì)問(wèn):
* 有辦法將 stderr 也餵進(jìn)下一個(gè)命令的 stdin 去嗎?
(貪得無(wú)厭的家夥﹗)
方法當(dāng)然是有,而且你早已學(xué)過(guò)了﹗ ^_^
我提示一下就好:
* 請(qǐng)問(wèn)你如何將 stderr 合併進(jìn) stdout 一同輸出呢?
若你答不出來(lái),下課之後再來(lái)問(wèn)我吧... (如果你臉皮真夠厚的話...)

或許,你仍意尤未盡﹗或許,你曾經(jīng)碰到過(guò)下面的問(wèn)題:
* 在 cm1 | cm2 | cm3 ... 這段 pipe line 中,若要將 cm2 的結(jié)果存到某一檔案呢?

若你寫成 cm1 | cm2 > file | cm3 的話,
那你肯定會(huì)發(fā)現(xiàn) cm3 的 stdin 是空的﹗(當(dāng)然啦,你都將水管接到別的水池了﹗)
聰明的你或許會(huì)如此解決:
  1. cm1 | cm2 > file ; cm3 < file
復(fù)制代碼

是的,你的確可以這樣做,但最大的壞處是:這樣一來(lái),file I/O 會(huì)變雙倍﹗
在 command 執(zhí)行的整個(gè)過(guò)程中,file I/O 是最常見(jiàn)的最大效能殺手。
凡是有經(jīng)驗(yàn)的 shell 操作者,都會(huì)盡量避免或降低 file I/O 的頻率。

那,上面問(wèn)題還有更好方法嗎?
有的,那就是 tee 命令了。
* 所謂 tee 命令是在不影響原本 I/O 的情況下,將 stdout 複製一份到檔案去。
因此,上面的命令行可以如此打:
  1. cm1 | cm2 | tee file | cm3
復(fù)制代碼

在預(yù)設(shè)上,tee 會(huì)改寫目標(biāo)檔案,若你要改為增加內(nèi)容的話,那可用 -a 參數(shù)達(dá)成。

基本上,pipe line 的應(yīng)用在 shell 操作上是非常廣泛的,尤其是在 text filtering 方面,
凡舉 cat, more, head, tail, wc, expand, tr, grep, sed, awk, ... 等等文字處理工具,
搭配起 pipe line 來(lái)使用,你會(huì)驚覺(jué) command line 原來(lái)是活得如此精彩的﹗
常讓人有"眾裡尋他千百度,驀然回首,那人卻在燈火闌珊處﹗"之感... ^_^

....

好了,關(guān)於 I/O Redirection 的介紹就到此告一段落。
若日後有空的話,再為大家介紹其它在 shell 上好玩的東西﹗bye... ^_^

[ 本帖最后由 網(wǎng)中人 于 2008-10-30 02:24 編輯 ]

論壇徽章:
0
68 [報(bào)告]
發(fā)表于 2004-01-17 17:36 |只看該作者

shell 十三問(wèn)?

謝謝您的貼子,受益良多!

論壇徽章:
0
69 [報(bào)告]
發(fā)表于 2004-01-19 15:28 |只看該作者

shell 十三問(wèn)?

原帖由 "網(wǎng)中人" 發(fā)表:

嗯,這個(gè)前面已經(jīng)討論過(guò)了,我不再重複了...


能解釋一下下面命令中的{}含義嗎?

find . -size +3000k -exec ls -ld {} \;

論壇徽章:
1
榮譽(yù)版主
日期:2011-11-23 16:44:17
70 [報(bào)告]
發(fā)表于 2004-01-19 16:29 |只看該作者

shell 十三問(wèn)?

這是 find 用的,而不是 shell ...

它用在 find 的 -exec 或 -ok 處理,用在其後 command line 中,依次代入 find 找到的結(jié)果。

請(qǐng) man find 及 man xargs (xargs 之 -i)...
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP