Назад | Перейти на главную страницу

Тестирование сценария, ожидающего stdin

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

Вот пример. Команда, которую я выполняю, требует много времени для выполнения, но она также будет запрашивать ввод перед запуском без приглашения. Я хочу знать, что команда действительно что-то делает, а не просто ждет.

Предоставлен следующий скрипт под названием ./demo

#!/bin/bash

read

Есть ли способ определить, что чтение ожидает stdin? Что-то вроде

failifwaitingonstdin | ./demo

Что немедленно вернется, как только будет обнаружена команда чтения.

Обновлено:

Люди предложили такие программы, как "ожидать" и "да". После того, как я раскопался, я понял, как они могут поддерживать такой стиль взаимодействия. Они постоянно используют fputs для записи y в stdout. Вместо того, чтобы делать это бесконечно, я могу просто вернуть ошибку, как только fputs вернется при записи в stdout.

Было бы действительно полезно, если бы вы были более конкретны в своем скрипте и / или команде. Но в случае, если вы хотите проверить, откуда берется stdin, этот пример сценария продемонстрирует это для вас:

#!/bin/bash
if [[ -p /dev/stdin ]]
then
    echo "stdin is coming from a pipe"
fi
if [[ -t 0 ]]
then
    echo "stdin is coming from the terminal"
fi
if [[ ! -t 0 && ! -p /dev/stdin ]]
then
    echo "stdin is redirected"
fi
read
echo "$REPLY"

Пример запускает:

$ echo "hi" | ./demo
stdin is coming from a pipe
$ ./demo
[press ctrl-d]
stdin is coming from the terminal
$ ./demo < inputfile
stdin is redirected
$ ./demo <<< hello
stdin is redirected
$ ./demo <<EOF
goodbye
EOF
stdin is redirected

Если вы используете Linux, вы можете использовать strace чтобы узнать, пытается ли процесс читать из стандартного ввода. На других платформах есть похожие программы (например, dtrace, ktrace, или truss).

Вы могли бы вообще избежать проблемы, загрузив вывод yes соответствующей команде.

Не зная, что вы пытаетесь сделать, я бы поспорил, что вам следует написать сценарий, чтобы вы всегда знали, будет ли он запрашивать стандартный ввод или нет. Либо это, либо передайте что-то в команду, которая, вероятно, что-то хочет от stdin, но это, вероятно, не лучшая идея.

Если вы пишете скрипты: bash's read builtin принимает параметр тайм-аута:

read -p prompt -t 5 var # 5s timeout

Если нет, вы можете использовать expect, или просто yes, чтобы имитировать взаимодействие с пользователем.