web-dev-qa-db-ja.com

/ dev / nullにリダイレクトする

私は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ファイルに圧縮する方法がわからないため、あらゆる種類のエラーが発生する可能性があります。

179
JohnMerlino

いいえ、これはスクリプトのクラッシュを防ぐことはできません。 tarプロセスでエラーが発生した場合(例:権限が拒否された、そのようなファイルやディレクトリがないなど)、スクリプトは引き続きクラッシュします。

これは、> /dev/null 2>&1を使用すると、すべてのコマンド出力(stdoutstderrの両方)が/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
266
cuonglm

ここで ">/dev/null 2>&1"の使用を理解しようとしています。

(質問の/dev/nullの前にリダイレクトを追加したことに注意してください。)

上記はSTDOUTおよびSTDERR/dev/nullにリダイレクトします。 STDERRSTDOUTにマージすることで機能します。 (基本的に、コマンドからのすべてのoutputnull device にリダイレクトされます。)

...スクリプトをクラッシュさせることなく(プログラミング言語で例外処理をキャッチしようとするようなものです)。

try/catchなどとはまったく異なります。コマンドからのあらゆる種類の出力(エラーを含む)を単にsilencesします。

Tarを使用してディレクトリをtarファイルに圧縮する方法がわからないため、あらゆる種類のエラーが発生する可能性があります。

次のようないくつかの理由でエラーが発生する可能性があります。

  • アーカイブしようとしているファイルまたは書き込みしようとしているファイルに対する不適切なアクセス許可
  • アーカイブを作成するためのディスク容量の不足
23
devnull

CMD>/dev/null 2>&1を実行すると

STDOUTは/ dev/nullにリダイレクトし、次にSTDERRは/ dev/nullに設定されているSTDOUTのTHE ADDRESSにリダイレクトします。その結果、STDOUTとSTDERRの両方が/ dev/nullを指します。

反対に、CMD 2>&1>/dev/nullを実行すると

STDERRはSTDOUTのTHE ADDRESS(その瞬間のファイル記述子1、または/ proc/self/fd/1)にリダイレクトし、次にSTDOUTは/ dev/nullにリダイレクトしますが、STDERRはfd1にリダイレクトし続けます!!その結果、STDOUTからの通常の出力は破棄されますが、STDERRからのエラーはまだコンソールに書き込まれています。

15
hector

簡単に理解できるように、明示的に記述してください。以下は、存在しないファイルを削除しようとするコマンドの例です。

rm nonexisting.txt 1>/dev/null 2>/dev/null
  • 1はstdoutです。/dev/nullに情報ログを送信する
  • 2はstderrです。エラーログを/ dev/nullに送信します

以下は、いくつかの拡張機能です(デフォルトとポインターを使用して、すべてのユーザーを混乱させます)。

拡張1: "1>"を ">"に置き換えることができます( "1"がデフォルトのstdoutであるため)

 rm nonexisting.txt >/dev/null 2>/dev/null

機能拡張2:2番目の「/ dev/null」を&1に置き換えることができます(2番目の/ dev/nullは&1と呼ばれます。これは、/ dev/nullが「stdout 1によってすでにポイントされているため」)

rm nonexisting.txt 1> /dev/null 2> &1
2
Thyag