
У меня есть команда, которая запрашивает у пользователя некоторые входные данные, а затем выводит результат на терминал. Я ввел команду, как показано ниже, чтобы перенаправить вывод в файл:
$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 из многих источников в Интернете.
- Как и предполагалСкоттв его комментарии естьвики-ответ Unix SE: хорошая отправная точка.
- Обязательно
man bash
илируководство по bash. - Я нашел полезной главу о перенаправленииbash-хакерыгде вы можете найти ссылки наустаревшие примененияслишком.
- Вы можете обратиться кРасширенное руководство по написанию сценариев Bash, глава 20 тоже.
решение2
По умолчанию только STDOUT
перенаправляется и/или передается по конвейеру. То, что вы хотите, это оставить STDOUT
в покое, и иметь все, что передается через STDIN
перенаправление.
Если редактирование the_command
является опцией, вы можете убедиться, что вопрос выводится STDERR
вместо этого (что должно выводить его на экран независимо от любых перенаправлений), а затем заставить его отображать все, что вводит пользователь, обратно на экран с помощью STDOUT
.
решение3
Обычно имеется два важных выходных канала: STDOUT
(для обычного вывода) и STDERR
(для сообщений об ошибках).
Проблема здесь в том, что "обычный" вывод команды и текст приглашения оба записываются в STDOUT
, поэтому они всегда помещаются в одно и то же место. Когда вы используете перенаправление, оно просто берет весь STDOUT
, включая приглашение.
Если переписать команду (как предложено в другом ответе Джармунда) невозможно, может быть, у команды есть дополнительная опция/флаг (например, --output
), которая может указать какой-то выходной файл вместо использования перенаправления?