Як програми виводяться в інше місце, ніж STDOUT / STDERR? Як цього уникнути?


15

Мабуть, я не знаю всіх вихідних напрямків, які доступні для використання. Я знаю про stdout( &1) та stderr( &2). Однак після перенаправлення обох дескрипторів я іноді все одно отримую деякий вихід у своїй консолі!

Найпростіший приклад, який я можу придумати, - це GNU Parallel; Кожного разу, коли я його використовую, я бачу повідомлення про цитування. Навіть коли я це роблю &2>1 > file, я все ще бачу повідомлення.

І те саме стосується emerge: Коли я запускаю, з’являються і виникають деякі проблеми, деякі відомості не надрукуються stdoutні stdin, оскільки я переадресовую їх, і вони все ще проходять.

Я здебільшого вирішую ці проблеми за допомогою script, але мені все ще цікаво, що викликає це питання.


1
Надайте повний приклад.
Kusalananda

яка оболонка? поглянути на mywiki.wooledge.org/BashFAQ/055 і stackoverflow.com/questions/876239 / ...
Sundeep

8
Ви не отримаєте їх усіх . Сценарій завжди можна писати в /dev/tty.
Satō Katsura

1
Що стосується GNU parallel: mkdir ~/.parallel; touch ~/.parallel/will-citeвідключить набридливе повідомлення. Крім того, огляньте інші реалізації parallel.
Satō Katsura

2
@OleTange Оскільки це не проблема - я запитую, чому щось відбувається, і я використовую parallelяк приклад.
MatthewRock

Відповіді:


40

Синтаксис, який ви використовували, неправильний.

cmd &2>1 >file

будуть розбиті як

cmd &
2>1 >file

Це буде:

  1. Запустити cmdяк фонове завдання без перенаправлень
  2. В окремому процесі (без команди!) Буде переадресовано stderrна файл, буквально викликаний 1і перенаправлений stdoutнаfile

Синтаксис, який ви бажаєте:

cmd >file 2>&1

Порядок операцій важливий. Це буде:

  1. Перенаправлення stdoutнаfile
  2. Перенаправлення stderr на &1- тобто той самий файл файлів, що іstdout

Результатом є те, що і те, і інше stderr і stdoutбудуть перенаправлені на file.

У bash, більш простий нестандартний синтаксис (і тому я його не рекомендую, з причини переносимості) cmd &> fileробить те саме.


Приємно, дякую. Інша проблема може бути /dev/tty, але, сподіваємось, це трапляється не дуже часто (якщо взагалі).
MatthewRock

5
Якщо у вас є atкоманда на вашій машині та маєте права користуватися нею, тоді ви можете запустити команду через at now. Докладніше див. На сторінці сторінки. Це запустить команду через пакетний механізм процесу, і процес ніколи не матиме Tty, щоб записати. Але, взагалі, я б не переймався цим краєм справи. Зазвичай використовуватимуться лише процеси, що вимагають взаємодії та свідомо необхідності показувати речі користувачам, незважаючи на перенаправлення /dev/tty.
Стівен Харріс

був там, зробив це
davidbak

10

Є дві проблеми.

Перший полягає в тому, що порядок має значення, другий /dev/tty.

Давайте використаємо цей скрипт як приклад сценарію, з якого ми хочемо отримати результат від:

test.sh:

#!/bin/bash

echo dada
echo edada 1>&2
echo ttdada >/dev/tty

Тепер давайте подивимося на результати команд:

./testmyscript.sh 2>&1 >/dev/null:

edada
ttdada

Оскільки порядок оцінювання знаходиться зліва направо, ми спочатку отримуємо "перенаправлення stderrтуди, куди stdoutвиводиться (так, консольний вихід)". Тоді ми переходимо stdoutдо "переспрямування" /dev/null. Ми закінчуємо ситуацію, як така:

stdout-> /dev/null stderr-> консоль

Тож ми все зрозуміємо:

./testmyscript.sh >/dev/null 2>&1

І ми отримуємо:

ttdada.

Тепер ми робимо "Перенаправлення stdoutна /dev/null", а потім "Перенаправляємо stderr туди, куди вказує stdout" (так, /dev/null). Ура!

Однак у нас все ще є проблема; програма друкує на /dev/tty. Зараз я не знаю, як виправити таку поведінку, тож вам, швидше за все, знадобиться script, але, сподіваємось, така поведінка не траплятиметься занадто часто.

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