Использование /dev/stdin
таким образом может быть проблематичным, поскольку вы пытаетесь получить дескриптор стандартного ввода, используя имя в файловой системе (/dev/stdin
), а не файловый дескриптор, который bash уже передал вам как стандартный ввод (файловый дескриптор 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
person
Austin Phillips
schedule
11.03.2013
if [[ $# = 0 ]] ; then read b ; else read b < "$1" ; fi
. Но я понятия не имею, зачем нужен такой обходной путь. - person ruakh   schedule 11.03.2013