переадресація на / dev / null


144

Я читаю приклад сценарію bash shell:

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

Я намагаюся зрозуміти використання "/ dev / null 2> & 1" тут. Спочатку я подумав, що цей скрипт використовує / dev / null для того, щоб витончено ігнорувати помилки, не спричиняючи збоїв скрипту (як-от спробувати обробляти винятки в мовах програмування). Оскільки я не бачу, як використання клавіш tar для стиснення каталогу у файл tar може, можливо, спричинити помилки.


3
Перенаправлення /dev/nullне запобіжить збоїв, але очистить вихідні потоки stdout та stderr. tarможе спричинити помилки різними способами. Можливо, у вас немає доступу для запису, файл може вже існувати тощо.
Sparhawk

3
Просто хитрість, щоб уникнути зайвих результатів. Що стосується того, чому tar може спричинити помилки: тому що цільовий каталог не існує, тому що джерело цього немає, тому що ви не маєте доступу для запису до цілі, або не читаєте до джерела, тому що tarнемає у вашому $ PATH, оскільки tarвийшов з ладу (ніколи не знаєте), тому що на пристрої не залишилось місця, оскільки tarзмінилася версія і тепер потрібен інший синтаксис, оскільки диск викликав помилку вводу / виводу. Я впевнений, що ти міг би знайти більше.
тердон

Відповіді:


223

Ні, це не завадить збій сценарію. Якщо в tarпроцесі трапляються якісь помилки (наприклад: відмовлено у дозволі, немає такого файлу чи каталогу, ...) сценарій все одно вийде з ладу.

Оскільки використання > /dev/null 2>&1буде перенаправляти весь ваш командний вихід (і stdoutта stderr) на /dev/null, тобто жодні виходи не друкуються на термінал.

За замовчуванням:

stdin  ==> fd 0
stdout ==> fd 1
stderr ==> fd 2

У сценарії ви використовуєте > /dev/nullпричину:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2

А потім 2>&1викликає:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout

3
Наскільки зрозуміло > /dev/null 2>&1, ця команда призводить до stderr ==> stdout, тому stderr все ще надрукується для stdout
Weishi Zeng

11
певно, не надто важливо, але що таке fd?
kev


7
Чому: CMD > /dev/null 2>&1працює, але CMD 2>&1 > /dev/nullвсе-таки дає мені STDERR?
dbmikus

3
Рекомендовано: Використовуйте 2>& 1в прикладах коду, щоб підкреслити, що число та амперсанд вважаються частиною оператора перенаправлення. Зазвичай для перенаправлення до файлу є пробіл між >і /path/to/file, перенаправлення на дескриптор файлу - це по суті те саме.
Хенк Лангевельд

21

Я намагаюся зрозуміти використання "> / dev / null 2> & 1" тут.

(зауважте, що я додав перенаправлення раніше /dev/nullу вашому запитанні.)

Вищезазначене переспрямувало б STDOUTі STDERRна /dev/null. Він працює шляхом об'єднання STDERRв STDOUT. (По суті, весь вихід з команди буде переспрямований на нульовий пристрій .)

... не спричиняючи аварійного завершення роботи сценарію (як-от спробувати обробляти винятки в мовах програмування).

Це не зовсім як try/catchабо щось подібне. Він просто замовчує будь-який вихід (включаючи помилку) з команди.

Оскільки я не бачу, як використання клавіш tar для стиснення каталогу у файл tar може, можливо, спричинити помилки.

Це може призвести до помилок з кількох причин, зокрема:

  • Неадекватні дозволи для файлів, які ви намагаєтесь архівувати, або для файлу, до якого ви намагаєтесь записати
  • Не вистачає місця на диску для створення архіву

добре пояснено.
Адітя Гупта

7

При запуску CMD> / dev / null 2> & 1

STDOUT переспрямовує на / dev / null, а потім STDERR перенаправляє на АДРЕСУ STDOUT, для якої встановлено / dev / null, отже, і STDOUT, і STDERR вказують на / dev / null

Навпаки, при запуску CMD 2> & 1> / dev / null

STDERR перенаправляє на АДРЕСУ STDOUT (Дескриптор файлу 1 в цей момент, або / proc / self / fd / 1), а потім STDOUT перенаправляє на / dev / null, але STDERR продовжує перенаправляти на fd1 !! В результаті нормальний вихід з STDOUT відкидається, але помилки, що надходять від STDERR, все ще записуються на консоль.


-2

Перенаправлення Bash I / O

Основна ідея, щоб очистити речі, полягає в наступному:

Переадресації застосовуються з ПРАВА на ЛІВО, навпаки, як зазвичай читають англійські мовці.


Отже цей код:

command > filename 2>&1

перенаправляє stderrдо stdout першої ( 2>&1) , а потім відправляє stdout( в тому числі перенаправлені stderr) , щоб filename( > filename). Ось пояснення щодо ABSG (гл. 20) .

Цей код:

command >>/dev/null 2>&1

переадресації stderrі stdoutна /dev/null... що означає нікуди . Речі, на які надсилаються /dev/null, жодним чином не зберігаються, зберігаються в кеш-пам'яті та не запам'ятовуються.

Їх просто відправляють у " нікуди " і забувають. Це спосіб запуску програм і переконайтеся, що вони не дають виводу NO і ніколи не будуть помічені в командному рядку або в файлі журналу.


Такого питання я бачу зовсім небагато ... головним чином тому, що мені довелося шукати його сам, оскільки не кодував років. Ось деякі зручні відомості з ABSG:

"Перенаправлення просто означає захоплення виводу з файлу, команди, програми чи сценарію та надсилання його як вхід до іншого файлу, команди, програми чи сценарію."

2>&1 
# Redirects stderr to stdout.

command >>filename 2>&1
# Appends both stdout and stderr
#+  to the file "filename" ...

ABSG: Advanced Bash Scripting Guide: Глава 20 Посилання вище є посилання на сторінку перенаправлення вводу / виводу з відкритим вихідним кодом tldp.org документа під назвою Advanced Bash Scripting Guide Менделем Купер. Він занесений як "Поглиблене дослідження мистецтва сценаріїв оболонок", і я абсолютно згоден. Це надзвичайний ресурс і має багато відповідей на всілякі шалені ситуації.

Інші цінні ресурси: У поточному / підтримуваному розділі (у кількох зручних форматах, таких як html, pdf, текст тощо) на сторінці посібників з документації Linux-документації є багато цінних ресурсів . Ось кілька мені корисних:


1
Ні, переадресації обробляються зліва направо. У вашому прикладі стандартний вихід переспрямовується filename, а потім стандартна помилка переспрямовується туди, куди зараз (на filename) йде стандартний вихід . Якби це було навпаки, стандартна помилка виявилася б на терміналі, тоді як тільки стандартний вихід буде переспрямований filename. Крім того , в command >file1 2>file2, file2не буде створена , якщо file1не може бути створений (незалежно від того , є чи file1й на file2самому ділі були абсолютно різні імена шляхів).
Kusalananda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.