2012-04-14 56 views
8

在bash,那麼你可以這樣做:是否有用於'>&0'(重定向到stdin)?

  • echo test >&1(重定向到標準輸出,但它已經去那裏)
  • echo test >&2(重定向到stderr)
  • echo test >&0(重定向到標準輸入)

當我做最後一個時,我的終端仍然會打印test,就像它與其他兩個打印機一樣,但很難知道原因。所以首先,爲什麼這個工作呢?其次,有沒有什麼好的用途來重定向到stdin?

回答

6

更確切地說,是什麼>&0確實是重複的文件描述符0作爲文件描述符1.如果程序的標準輸入只開放閱讀,那麼當你的程序試圖寫到標準輸出(文件描述符1),它會得到由於文件描述符1也僅用於讀取,所以出現錯誤。

10156115.sh:

#!/bin/bash 
bash -c 'ls -l /proc/$$/fd' >&0 

然後用可識別的標準輸入,輸出和錯誤調用它:

您可以通過編寫檢查自己的文件描述一個小的shell腳本證明這一點

$ touch stdin 
$ ./10156115.sh <stdin> stdout 2> stderr 

的結果是,你得到stderr如下:

ls: write error: Bad file descriptor 

但是,默認,所有三個是一個終端:(輸出簡化的)

$ ls -l /proc/$$/fd 
lrwx------ 0 -> /dev/pts/14 
lrwx------ 1 -> /dev/pts/14 
lrwx------ 2 -> /dev/pts/14 
lrwx------ 255 -> /dev/pts/14 

典型地,所有的三個實際上是開放讀+寫,所以>&0重定向沒有效果在所有如果單獨使用來自正常的外殼。


這是否有任何用處?

有沒有這個任何共同的用途,但如果任何人調用腳本重定向stdoutstderr,以任何理由,你是不是你可以使用它作爲一個骯髒的黑客獲得的方式打印到終端能夠更改:

if [ ! -t /dev/fd/1 -a ! -t /dev/fd/2 -a -t /dev/fd/0 ]; then 
    echo "My message that I really, really want to go to a terminal" >&0 
fi 

但我不會真的建議這樣做。

5

由於歷史的原因,終端上的標準文件描述符是以讀/寫方式而不是隻讀方式(具體來說,它被打開一次,並且dup()編輯給其他人)。這對於想要進行管道輸入但還可以讀取來自用戶的輸入(來自stdout或更常見的stderr)的程序偶爾是有用的,儘管在這種情況下使用/dev/tty更可靠。有些系統不僅僅適用於ttys:* BSD雙向打開socketpairs(「管道」),有些系統實用程序(我記得ufsdump是一個示例)依賴於此。

重定向stdin(即,具有它僅打開用於寫入)不是非常有用,因爲大多數程序期望它是開放讀(或有時讀/寫,如上述)。