Как перенаправить вывод команды в файл, если команда запрашивает ввод данных пользователем?

Как перенаправить вывод команды в файл, если команда запрашивает ввод данных пользователем?

У меня есть команда, которая запрашивает у пользователя некоторые входные данные, а затем выводит результат на терминал. Я ввел команду, как показано ниже, чтобы перенаправить вывод в файл:

$the_command > abc.txt

Но это не работает. Проблема в том, что нет подсказки, текст этих подсказок выводится в abc.txt, а не тот результат, который мне нужен.

решение1

Ваша команда работает и правильно перенаправляет вывод в файл abc.txt.
Вопрос в том,как ваш скрипт запрашивает входные данныеи как вы запускаете скрипт?
Давайте посмотрим на двух примерах:

# Script_1.sh                                     # 1
echo Please, enter your firstname and lastname    # 2
read FN LN                                        # 3
echo "Hi! $LN, $FN !"                             # 4

и

# Script_2.sh                                     # 5
read -p "Enter a comment " CM                     # 6
echo  "You said $CM"                              # 7

Если вы запустите, /bin/bash Script1.sh > abc.txtвы не увидите вопрос "Пожалуйста, введите..." на вашем tty. Если вы дадите ожидаемый ввод с клавиатуры, вы найдете вывод строк № 2 и № 4 в вашем abc.txtфайле.

Если вы запустите, /bin/bash Script2.sh > abc.txtто увидите вопрос «Введите комментарий», но в файле вы найдете abc.txtтолько вывод строки №7.

Примечание: если вы запускаете Script2,sh в подоболочке

(bash Script2.sh 2>&1)> abc.txt

вы не увидите никакого вывода на tty и вы найдете все в файле abc.txt.
Если вы запустите его с

bash Script2.sh 2>ccc.txt 1>ddd.txt`

ddd.txtСтандартный вывод (строка №7) и стандартную ошибку (строка №6) вы найдете в ccc.txt.


Если ты хочешьдля перенаправления только части вывода вашей командывам нужно изменить ваш скрипт.
Один из способов сделать это — создать функцию, в которую переместить часть скрипта, которая будет генерировать интересный вывод (см. ниже). Затем вы можете вызвать эту функцию изГлавная частьвашего скрипта (где изначально был код, который вы переместили в функцию), перенаправив только этот вывод в файл журнала:

 Part_To_Redirect(){
     : # all that you want
 }

 # ... Main part of the script
 # point where it was the part that generates the output
 Part_to_Redirect "$@" > abc.txt   # this to store only that part in the file
 # Part_to_Redirect "$@" >> abc.txt  # this to append that part in the file
 # ...

Вы даже должны найти полезнымteeчто

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

 the_command  | tee abc.txt       # To redirect Standard output
 or 
 the_command 2>&1 | tee abc.txt   # To redirect err in out and both in the file

В этом случае вы будете иметь нормальные выходные данные вашей команды на tty, но в то же время вы сохраните копию в файле журнала abc.txt. Это должно быть удобно в вашем случае, если вы используете, read -pкак в script2, вызов the_command | tee abc.txt.

Примечания и ссылки:

Добавляя, "$@"вы можетепередать все аргументывашего скрипта к функции.

Возможно, вам будет интересно почитать больше о bashredirection из многих источников в Интернете.

решение2

По умолчанию только STDOUTперенаправляется и/или передается по конвейеру. То, что вы хотите, это оставить STDOUTв покое, и иметь все, что передается через STDINперенаправление.

Если редактирование the_commandявляется опцией, вы можете убедиться, что вопрос выводится STDERRвместо этого (что должно выводить его на экран независимо от любых перенаправлений), а затем заставить его отображать все, что вводит пользователь, обратно на экран с помощью STDOUT.

решение3

Обычно имеется два важных выходных канала: STDOUT(для обычного вывода) и STDERR(для сообщений об ошибках).

Проблема здесь в том, что "обычный" вывод команды и текст приглашения оба записываются в STDOUT, поэтому они всегда помещаются в одно и то же место. Когда вы используете перенаправление, оно просто берет весь STDOUT, включая приглашение.

Если переписать команду (как предложено в другом ответе Джармунда) невозможно, может быть, у команды есть дополнительная опция/флаг (например, --output), которая может указать какой-то выходной файл вместо использования перенаправления?

Связанный контент