Як перенаправити вихід на кілька файлів журналу


52

Як перенаправити стандартний вихід на кілька файлів журналу? Наступне не працює:

some_command 1> output_log_1 output_log_2 2>&1

6
З zsh, ви можете використовувати some_command >output_log_1 >output_log_2.
jofel

Відповіді:


70

Дивіться man tee:

НАЗВА: tee - читати зі стандартного вводу та записувати на стандартний вихід та файли

СИНОПИС: трійник [ВАРІАНТ] ... [ФАЙЛ] ...

Відповідно:

echo test | tee file1 file2 file3

може stderr також бути перенаправлений у більш ніж один файл?
fromnaboo

Так, це можна зробити за допомогою перенаправлення: test / -name test 2> & 1 | tee file1 file2 file3
akond

@akond, cmd 2>&1 | tee log1 log2 я спробував виконати як вище, але мені потрібно натиснути ctrl-c, щоб перенаправити його на другий файл журналу. також вихід друкується на консолі. Я хочу, щоб командний результат був перенаправлений на журнали, але не на консоль. будь-яка допомога цінується.
doubledecker

@doubledecker teeКоманда записує stdinу файл (и), а також в stdout. Якщо ви не хочете, щоб вихід відображався на терміналі, вам доведеться перенаправляти так, /dev/nullяк зазвичай.
Мінікс

4
Можливо також додавання до декількох файлів:echo test | tee --append file1 file2
user1364368

13

Скажімо, ваш вихід генерується з функції cmd():

cmd() {
    echo hello world!
}

Для перенаправлення виводу з cmdдвох файлів, але не до консолі, ви можете використовувати:

cmd | tee file1 file2 >/dev/null

Це буде працювати для декількох файлів, враховуючи будь-яке джерело даних, яке проходить до трійника:

echo "foobarbaz" | tee file1 file2 file3 file4 > /dev/null

Це також буде працювати:

echo $(cmd) | tee file1 file2 >/dev/null

Без /dev/nullперенаправлення, tee надішле вихід на stdout на додаток до вказаних файлів.

Наприклад, якщо це запускається з консолі, ви побачите там вихід. Запустившись з кронтабуляції, на виході з’явиться повідомлення про стан, яке вам надіслано (див. Також відповідь Гілла тут https://unix.stackexchange.com/a/100833/3998 ).

Це працювало для мене в bash на Ubuntu 12.04 і було підтверджено в Ubuntu 14.04 за допомогою GNU bash 4.3.11 (1), тому він повинен працювати на будь-якій останній версії bash GNU.


@doubledecker - схоже, що він відповідає вашим умовам, тому його можна прийняти як відповідь. Також +1, як я тестував це під GNU bash ( version 4.3.11(1)-release (i686-pc-linux-gnu)) в Ubuntu 14.04.
belacqua

9

Це стара публікація, але я зараз її знайшов ...

Замість того, щоб перенаправляти вихід до нього, > /dev/nullви можете перенаправити його на останній файл:

echo "foobarbaz" | tee file1 > file2

Або для додавання виводу:

echo "foobarbaz" | tee -a file1 >> file2

це більш-менш те, що сказала інша відповідь (за винятком -a трійника)
Архемар

Це шлях.
71ГА

5

Як згадував @jofel у коментарі під відповіддю, це можна зробити на самому місці zsh:

echo foobar >file1 >file2 >file3

або, з розширенням дужок:

echo foobar >file{1..3}

Всередині це працює дуже подібно до teeвідповідей, поданих вище. Оболонка з'єднує stdout команди з процесом, який передає декілька файлів; Таким чином, немає ніяких переконливих технічних переваг , щоб робити це таким чином (але це дійсно виглядають дійсно добре). Докладніше див. У zshпосібнику .


2

Однак неможливо прокоментувати інший спосіб висловити

echo "foobarbaz" | tee file1 file2 file3 file4 file5 file6 file7 file8 > /dev/null

Це може бути спрощено до цього при роботі з багатьма файлами.

echo "foobarbaz" | tee file{1..8} > /dev/null

2
Чим це насправді відрізняється від інших вже відповідей? Тим більше , що деякі люди , ймовірно , хочуть буквальних file1через , file8як їх імена , і ті швидше за все лише приклад наповнювачі для імен файлів
Ерік Ренуф

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