以這種方式使用/dev/stdin
可能是有問題的,因爲你正試圖獲得一個句柄在文件系統(/dev/stdin
)使用一個名稱,標準輸入,而不是使用文件描述符哪個bash已經把你作爲stdin(文件描述符0)交給你。
這裏有一個小的腳本爲您測試:
#!/bin/bash
echo "INFO: Listing of /dev"
ls -al /dev/stdin
echo "INFO: Listing of /proc/self/fd"
ls -al /proc/self/fd
echo "INFO: Contents of /tmp/sh-thd*"
cat /tmp/sh-thd*
read b < "${1-/dev/stdin}"
echo "b: $b"
在我的Cygwin安裝這將產生以下:
./s <<< 'Hello world'
$ ./s <<< 'Hello world'
INFO: Listing of /dev
lrwxrwxrwx 1 austin None 15 Jan 23 2012 /dev/stdin -> /proc/self/fd/0
INFO: Listing of /proc/self/fd
total 0
dr-xr-xr-x 2 austin None 0 Mar 11 14:27 .
dr-xr-xr-x 3 austin None 0 Mar 11 14:27 ..
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 0 -> /tmp/sh-thd-1362969584
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 1 -> /dev/tty0
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 2 -> /dev/tty0
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 3 -> /proc/5736/fd
INFO: Contents of /tmp/sh-thd*
cat: /tmp/sh-thd*: No such file or directory
./s: line 12: /dev/stdin: No such file or directory
b:
什麼這個輸出顯示的是bash的是創建一個臨時文件來保存你的HERE文件(/tmp/sh-thd-1362969584
),並使其在文件描述符0,stdin上可用。但是,臨時文件已從文件系統中斷開連接,因此無法通過文件系統名稱(如/dev/stdin
)進行參考。您可以通過讀取文件描述符0來獲取內容,但不能嘗試打開/dev/stdin
。
在Linux上,上面的./s
腳本提供了以下,表明該文件已被解除鏈接:使用
INFO: Listing of /dev
lrwxrwxrwx 1 root root 15 Mar 11 09:26 /dev/stdin -> /proc/self/fd/0
INFO: Listing of /proc/self/fd
total 0
dr-x------ 2 austin austin 0 Mar 11 14:30 .
dr-xr-xr-x 7 austin austin 0 Mar 11 14:30 ..
lr-x------ 1 austin austin 64 Mar 11 14:30 0 -> /tmp/sh-thd-1362965400 (deleted) <---- /dev/stdin not found
lrwx------ 1 austin austin 64 Mar 11 14:30 1 -> /dev/pts/12
lrwx------ 1 austin austin 64 Mar 11 14:30 2 -> /dev/pts/12
lr-x------ 1 austin austin 64 Mar 11 14:30 3 -> /proc/10659/fd
INFO: Contents of /tmp/sh-thd*
cat: /tmp/sh-thd*: No such file or directory
b: Hello world
更改腳本的標準輸入提供的,而不是試圖通過/dev/stdin
引用。
if [ -n "$1" ]; then
read b < "$1"
else
read b
fi
在你的情況,順便說一句,可以很容易地解決這個寫'如果[$#= 0 ]];然後讀b;否則讀b <「$ 1」; fi'。但我不知道爲什麼這樣的解決方法應該是必要的。 – ruakh 2013-03-11 02:58:31