Прямий вихід з команди у файл, що включає оригінальну команду, та друк у терміналі


8

Під час виконання деяких тестів мені потрібно виконати ряд команд. Це було б дуже корисно для мене і заощадило б мені багато часу, якби був спосіб зробити все це:

  • Виконай команду, яку мені потрібно виконати
  • Перенаправити весь вихід з команди на вказаний файл
  • Включіть оригінальну команду у вказаний файл
  • Роздрукуйте вихід з оригінальної команди в терміналі

Люди запропонували мені використати трійник, який чудово справляється з друком на термінал, а також надсиланням у файл, але не включає оригінальну команду. Що я хотів би закінчити, це файл, де перший рядок - це команда, яку я запустив, а нижче - це вихід з команди.

Хтось запропонував це:

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

Але це не друкує висновок у терміналі, а також не включає оригінальну команду у файл.

Буду вдячний за будь-які ідеї.



Я не знайшов цього в пошуку - не зовсім те саме, але, мабуть, привів би мене до відповіді.
shaneoh

так, і саме тому я сказав майже дублікат. Але якщо бути абсолютно чесним з моєї думки, ви можете взяти звідти практично будь-яке рішення і скористатися ним, використовуючи трубопроводи tee.
Сергій Колодяжний

Відповіді:


14

Це teeви шукаєте.

ls -l | tee outfile

друкує висновок ls -lstdout (тобто термінал) і outfileодночасно зберігає його у файлі . Але : Це ім'я команди не записує ні до stdout, ні у файл. Для цього просто 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.


9

Ви можете скористатися 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

Тоді, якщо я 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

6

Ви можете використовувати функцію налагодження оболонки разом із 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.