Я читаю пример сценария оболочки bash:
#!/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 может привести к любому типу ошибок.
bash-script
null
JohnMerlino
источник
источник
/dev/null
не предотвратит сбой, но очистит выходные потоки stdout и stderr.tar
может вызвать ошибки различными способами. Возможно, у вас нетtar
нет в вашем $ PATH, потому чтоtar
сбой (вы никогда не знаете), потому что на устройстве не осталось места, потому чтоtar
версия изменилась и теперь требует другого синтаксиса, потому что диск вызвал ошибку ввода-вывода. Я уверен, что вы могли бы найти больше.Ответы:
Нет, это не предотвратит сбой скрипта. Если в
tar
процессе происходят какие-либо ошибки (например, отказано в разрешении, нет такого файла или каталога, ...), скрипт все равно будет аварийно завершать работу.Потому что использование
> /dev/null 2>&1
перенаправит все выходные данные вашей команды (какstdout
иstderr
)/dev/null
, что означает, что выходные данные не выводятся на терминал.По умолчанию:
В сценарии вы используете
> /dev/null
вызывающий:А потом
2>&1
вызывает:источник
> /dev/null 2>&1
, эта команда приводит к томуstderr ==> stdout
, что stderr все еще печатается в stdout ??fd
?CMD > /dev/null 2>&1
работает, ноCMD 2>&1 > /dev/null
все еще дает мне STDERR?2>& 1
в примерах кода, чтобы подчеркнуть, что число и амперсанд считаются частью оператора перенаправления. Обычно для перенаправления в файл между пробелами>
и пробелом/path/to/file
, перенаправление в файловый дескриптор, по сути, одно и то же.(обратите внимание, что я добавил перенаправление раньше
/dev/null
в вашем вопросе.)Выше будет перенаправить
STDOUT
иSTDERR
к/dev/null
. Это работает путем слиянияSTDERR
вSTDOUT
. (По существу, все выходные данные команды будут перенаправлены на нулевое устройство .)Это не совсем похоже на
try/catch
что-нибудь. Он просто отключает любой вывод (включая ошибку) команды.Это может привести к ошибкам по ряду причин, в том числе:
источник
Когда вы запускаете 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, все еще записываются на консоль.
источник
Bash I / O Redirection
Основная идея прояснить это так:
Итак, этот код:
перенаправляет
stderr
наstdout
first (2>&1
), а затем отправляетstdout
(включая перенаправленныеstderr
) наfilename
(> filename
). Вот объяснение ABSG (гл. 20) .Этот код:
перенаправляет
stderr
иstdout
в/dev/null
... что означает в никуда . Отправленные вещи/dev/null
не сохраняются, не кэшируются и не запоминаются каким-либо образом.Их просто отправляют в « никуда » и забывают. Это способ запуска программ и проверки того, что они НЕ выдают никаких результатов и никогда не будут отображаться в командной строке или в файле журнала.
Я вижу этот тип вопросов довольно часто ... в основном потому, что мне самому пришлось его искать, так как я не программировал годами. Вот некоторая полезная информация из ABSG:
«Перенаправление просто означает захват вывода из файла, команды, программы или сценария и отправку его в качестве ввода в другой файл, команду, программу или сценарий».
ABSG: Advanced Bash Scripting Guide: Глава 20 Ссылка выше является ссылка на страницу перенаправления ввода / вывода с открытым исходным кодом tldp.org документа под названием Advanced Bash Scripting Guide Менделем Купер. Он указан как «Углубленное исследование искусства сценариев оболочки», и я абсолютно согласен. Это потрясающий ресурс, на котором есть множество ответов на все безумные ситуации.
Другие ценные ресурсы: в текущем / поддерживаемом разделе есть много ценных ресурсов (в нескольких удобных форматах, таких как html, pdf, text и т. Д.) На странице руководств по проектам документации для Linux . Вот некоторые из них, которые я нашел полезными:
источник
filename
, а затем стандартная ошибка перенаправляется туда, куда направляется стандартный вывод (вfilename
). Если бы все было наоборот, стандартная ошибка заканчивалась на терминале, а перенаправлялся только стандартный выводfilename
. Кроме того , вcommand >file1 2>file2
,file2
не будет создан , еслиfile1
не может быть создан (независимо от того , является лиfile1
и наfile2
самом деле были совершенно разные имена путей).