Тестирование для сценария, который ожидает на стандартном вводе
Есть ли способ определить, ожидает ли скрипт на стандартном вводе и вызвать команду для выхода, если обнаружен?
Вот пример, выполнение команды, которую я выполняю, занимает много времени, но она также будет запрашивать ввод перед запуском без приглашения. Я хочу знать, что команда на самом деле что-то делает, а не просто ждет.
При условии, что следующий скрипт называется./demo
#!/bin/bash
read
Есть ли способ обнаружить, что чтение ожидает на стандартный ввод? Что-то вроде
failifwaitingonstdin | ./demo
Который немедленно вернется, как только будет обнаружена команда чтения.
Обновлено:
Люди предложили программы, как ожидать и да. Пройдя через да, я вижу, как они могут поддерживать этот стиль взаимодействия. Они постоянно используют fputs для записи 'y' в стандартный вывод. Вместо того, чтобы делать это бесконечно, я могу просто вернуть ошибку, как только fputs вернёт запись в stdout.
4 ответа
Было бы очень полезно, если бы вы были более конкретны в своем сценарии и / или команде. Но в случае, если вы хотите проверить, откуда исходит 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
Если вы пишете сценарии: bash's read Встроенный принимает опцию тайм-аута:
read -p prompt -t 5 var # 5s timeout
Если нет, вы можете использовать expect, или просто yes, чтобы подделать взаимодействие с пользователем.
Если вы используете Linux, вы можете использовать strace чтобы увидеть, пытается ли процесс читать со стандартного ввода. Другие платформы имеют аналогичные программы (например, dtrace, ktrace, или же truss).
Вы могли бы вообще избежать этой проблемы, подавая вывод yes к рассматриваемой команде.
Не зная, что вы пытаетесь сделать, я бы поспорил, что вы должны писать сценарий, чтобы вы всегда знали, будет ли он запрашивать стандартный ввод или нет. Либо это, либо что-то в команду, которая, вероятно, хочет чего-то от stdin, но это, вероятно, не лучшая идея.