Попробуйте сначала прочитать строку из stdin:
IFS= read -r line if [[ -n "$line" ]]; then # the line is non-empty. # add the line back into the stream and pipe it into your program { echo "$line"; cat -; } | your_program fi
Я хотел бы сделать:
if not eof(stdin): pass stdin to program else: do nothing
У меня есть ощущение, что это может быть написано довольно близко к:
if test ! --is-eof - ; then exec program
Проблема, которую я пытаюсь решить, заключается в том, что program
читает из стандартного ввода, но падает, если он не получает ввода. У меня нет доступа к источнику, program
поэтому program
не может быть изменено. Бинарный ввод больше, чем объем памяти, поэтому ввод stdin в файл сначала недопустимо медленен. Строковая обработка всех входных данных в bash также недопустимо медленная.
В идеале решение должно работать как под csh, так и под bash.
Попробуйте сначала прочитать строку из stdin:
IFS= read -r line if [[ -n "$line" ]]; then # the line is non-empty. # add the line back into the stream and pipe it into your program { echo "$line"; cat -; } | your_program fi
This seems to work in both csh and bash and deal nicely with binary input (also \0 as first char):
# Set $_FIRST_CHAR_FILE to the name of a temp file. eval `echo $SHELL | grep -E "/(t)?csh" > /dev/null && echo setenv _FIRST_CHAR_FILE /tmp/$$.first_char_file || echo export _FIRST_CHAR_FILE=/tmp/$$.first_char_file` dd bs=1 count=1 of=$_FIRST_CHAR_FILE >&/dev/null test -s "$_FIRST_CHAR_FILE" && ( cat $_FIRST_CHAR_FILE; rm $_FIRST_CHAR_FILE; cat - ) | program
Thanks to @glenn-jackman for giving the idea of reading a little bit before passing this and the rest of stdin through cat
.
Какой ввод ожидает ваша программа? вы передаете вывод из одной программы в другую или он читает файл?
Если вы используете перенаправление канала для сбора входных данных в свой скрипт, то он будет выполняться до тех пор, пока не будет предоставлена входная информация.
если вы пытаетесь читать из файла, используйте «while» или «then» для выполнения работы.
I post here since this came up when searching and since it helped me debugging on Darwin (snow leopard) bash in set -x;trap 'test -s /dev/stdin||exit' debug
to find a call that was consuming the inherited input of the parent script.
For the faint-hearted:
if [[ -s /dev/fd/0 ]] then echo 'Not at EOF' else echo 'Currently no input to read' fi
echo $((echo|test -s /dev/stdin)&&! (true|test -s /dev/stdin)&&echo pass||echo fail) $
The above test yields the following in my bash versions and systems.
pass 4 2 45 2 release i386-apple-darwin10.8.0
pass 3 2 48 1 release x86_64-apple-darwin10.0
fail 4 2 37 1 release x86_64-pc-linux-gnu
Piping to cat /proc/self/fdinfo/0
on my Debian (wheezy) gives nothing to test for either.
CheerIO or rather cheerEO for Erroneous/Output %)
Если вы не хотите, чтобы ваш скрипт блокировался при попытке найти что-то для чтения, вы можете (по крайней мере, в bash) использовать чтение с тайм-аутом
$ ( read -t 0 var ; echo $? ) 1 $ echo foo | ( read -t 0 var ; echo $? ) 0
Это, однако, не гарантирует, что у вас есть EOF, но что сейчас нечего читать