Порядок переадресацій


29

Я не зовсім розумію, як комп'ютер читає цю команду.

cat file1 file2 1> file.txt 2>&1

Якщо я розумію, 2>&1просто перенаправляйте Стандартну помилку на стандартний вихід.

За цією логікою команда читає мені наступне:

  1. об'єднати файли file1та file2.

  2. надіслати stdoutз цієї операції на file.txt.

  3. надіслати stderrна stdout.

  4. кінець?

Я не впевнений, що робить комп’ютер. За моєю логікою, команда повинна бути

cat file1 file2 2>&1 > file.txt

але це не правильно.

Відповіді:


46

Мені легше думати про використання завдань.

  • > це як =
  • & це як $

Ви починаєте з

1 = /dev/tty
2 = /dev/tty

то ваш перший приклад 1> file.txt 2>&1,, робить

1 = file.txt
2 = $1           # and currently $1 = file.txt

залишаючи тебе

1 = file.txt
2 = file.txt

Якщо ви зробили це по-іншому, знову почніть з

1 = /dev/tty
2 = /dev/tty

то 2>&1 > file.txtробить

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

тому кінцевий результат є

1 = file.txt
2 = /dev/tty

і ви лише перенаправлені stdout, ні stderr.


Я начебто отримую аналогію, але це заплутано - що означає $позиція?
Еліран Малька

У призначенні , як var=$othervar, $вводить ім'я змінної на правій стороні. У перенаправлення , як 2>&1, &вводить номер дескриптора файлу , на правій стороні. Я кажу, що ви можете подумати про це як "файл 2 дорівнює файлу 1". (Але є два типи рівних: <означає "для читання" і >означає "для письма".)
Мікель,

12

Порядок перенаправлення важливий, і їх слід читати зліва направо .

Наприклад: command 2>&1 >somefileозначає:

  1. Перенаправлення stderr(а саме 2) на поточне місце призначення stdout(у цей момент термінал).
  2. Потім змініть, stdoutщоб перейти somefile.

Тож у цьому випадку stderrйде до терміналу і stdoutпереходить до файлу, який не є тим, що ви, мабуть, хочете.

З іншого боку, command >somefile 2>&1означає:

  1. Перенаправлення stdoutнаsomefile
  2. Потім перенаправляємо stderrна те саме призначення, що і stdout( somefile).

В останньому випадку обидва stderrй stdoutпереходите до цього somefile, що, мабуть, ви хочете.


4
cat file1 file2 1> file.txt 2>&1

>& Насправді означає дублікат, він використовує системний виклик дублювання, щоб зіставити новий дескриптор файлу на вже відкритий файл.

Отже, ви (насправді bash) повинні спочатку відкрити нову stdout, сказавши "і перенаправити stderr до того, на що встановлено stdout".


Це круто! мені було цікаво про це &. Ви можете додати кілька посилань на цей синтаксис, або - ще краще - якісь хороші ресурси у вищезгаданій системі дублювання?
Еліран Малька

1
"man dup" документує системний виклик.
X Tian

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