2

Я хотел бы сделать:

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.

5 ответов5

1

Кажется, что это работает как в csh, так и в bash, и прекрасно справляется с двоичным вводом (также \0 в качестве первого символа):

# 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

Спасибо @ glenn-jackman за идею почитать немного перед тем, как пропустить это и остальную часть stdin через cat .

1

Попробуйте сначала прочитать строку из 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
0

Какой ввод ожидает ваша программа? вы передаете вывод из одной программы в другую или он читает файл?

Если вы используете перенаправление канала для сбора входных данных в свой скрипт, то он будет выполняться до тех пор, пока не будет предоставлена входная информация.

если вы пытаетесь читать из файла, используйте "while" или "then" для выполнения работы.

0

Если вы не хотите, чтобы ваш скрипт блокировался при попытке найти что-то для чтения, вы можете (по крайней мере, в bash) использовать чтение с тайм-аутом

$ ( read -t 0 var ; echo $? )
1

$ echo foo | ( read -t 0 var ; echo $? )
0

Это, однако, не гарантирует, что у вас есть EOF, но что сейчас нечего читать

0

Я пишу здесь, так как это произошло при поиске, и поскольку это помогло мне отладить Дарвин (снежный барс) в bash в отладке set -x;trap 'test -s /dev/stdin||exit' debug чтобы найти вызов, который потреблял унаследованный ввод родительского скрипта.

Для слабонервных:

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) ${BASH_VERSINFO[*]}

Приведенный выше тест выдает следующее в моих версиях и системах bash.

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

Пропуск в cat /proc/self/fdinfo/0 на моем Debian (wheezy) ничего не дает для проверки.

CheerIO или, вернее, cheerEO для ошибочных /% выхода)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .