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

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

  • Запустить команду, которую нужно выполнить
  • Перенаправить весь вывод команды в указанный файл
  • Включить исходную команду в указанный файл
  • Распечатать вывод исходной команды в терминале

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

Кто-то предложил это:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Но это не распечатывает вывод в терминале и не включает оригинальную команду в файл.

Буду признателен за любые идеи.

8
задан 28 November 2017 в 12:13

3 ответа

Это tee вы ищете.

ls -l | tee outfile

печатает вывод ls -l на стандартный вывод (то есть терминал) и одновременно сохраняет его в файл outfile. Но : Имя команды не записывается ни в стандартный вывод, ни в файл. Чтобы достичь этого, просто echo имя команды перед запуском команды и конвейер оба выводите на tee:

( echo "ls -l" && ls -l ) | tee outfile

Это громоздко для ввода, так почему бы не определить функцию?

both(){ ( echo "$@" && "$@" ) | tee outfile ;}

После этого вы можете просто запустить

both ls -l

, чтобы получить желаемый результат. Поместите функцию в свой ~/.bashrc, чтобы она была определена в каждом новом терминале.

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

both output ls -l

, вместо этого сделайте его:

both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}

Если вы не хотите выводить файл, который нужно перезаписать, но лучше добавить к нему, добавить опцию -a в tee.

14
ответ дан 28 November 2017 в 12:13

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

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Тогда, если I cat my_output, я получаю тот же результат:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC
8
ответ дан 28 November 2017 в 12:13

Вы можете использовать функцию отладки оболочки вместе с tee:

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... ) запускает вспомогательную оболочку, которая позволяет «собирать» выходные данные потоки всех команд, выполняемых внутри под-оболочки. Он также содержит эффект команды set ниже для этой вложенной оболочки.

  • set -x включает опцию оболочки x, которая печатает все команды, которые оболочка запускает, в стандартный поток ошибок перед их выполнением.

  • 2>&1 перенаправляет поток 2 (стандартная ошибка) в поток 1 (стандартный вывод).

  • | перенаправляет стандартный поток вывода левой команды в стандартный поток ввода правой команды.

  • tee FILE копирует стандартный поток ввода в файл FILE и на стандартный вывод.

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

bash -x /path/to/script args... 2>&1 | tee output.log
5
ответ дан 28 November 2017 в 12:13

Другие вопросы по тегам:

Похожие вопросы: