リダイレクトに関するいくつかのトリック
これに関する構文の特殊性には、重要な動作がある場合があります。リダイレクトは約いくつかの小さなサンプルがありSTDERR
、STDOUT
、と引数の順序。
1-上書きまたは追加?
記号>
はリダイレクトを意味します。
>
完成したファイル全体を送信することを意味し、存在する場合はターゲットを上書きします(後で#3のnoclobber
bash機能を参照)。
>>
存在する場合、ターゲットに追加するほかに送信することを意味します。
いずれにしても、ファイルが存在しない場合は作成されます。
2- シェルコマンドラインは順序に依存します!!
これをテストするには、両方の出力で何かを送信する単純なコマンドが必要です。
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
(/tnt
もちろん; という名前のディレクトリがないことを期待しています。)まあ、それがあります!
だから、見てみましょう:
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
最後のコマンドラインSTDERR
はコンソールにダンプし、予想される動作ではないようです...しかし...
1つの出力、他の出力、またはその両方についてポストフィルタリングを行う場合:
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
この段落の最後のコマンドラインは、前の段落とまったく同じであることに注意してください。ここで、私が書いたところは、予期された動作ではないようです(したがって、これは予期された動作である可能性もあります)。
さて、両方の出力で異なる操作を行うために、リダイレクトに関する小さなトリックがあり
ます:
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
注意:&9
記述子が原因で、自然に発生します) 9>&2
。
補遺:nota!新しいバージョンのバッシュ(>4.0
)この種のことを行うための新しい機能とよりセクシーな構文があります:
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
そして最後に、そのようなカスケード出力フォーマットについて:
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
補遺:nota!どちらの方法でも同じ新しい構文:
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
STDOUT
特定のフィルターを通過する場所から、別のフィルターを通過し、STDERR
最後にマージされた両方の出力は、3番目のコマンドフィルターを通過します。
3- noclobber
オプションと>|
構文について
それは上書きについてです:
既存のファイルを上書きset -o noclobber
しないようにbashに指示する一方で、>|
構文によりこの制限を通過させることができます。
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
ファイルは毎回上書きされるようになりました。
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
を通過>|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
このオプションの設定を解除するか、すでに設定されている場合は問い合わせます。
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4-最後のトリックなど...
特定のコマンドから両方の出力をリダイレクトする場合、正しい構文は次のようになります。
$ ls -ld /tmp /tnt >/dev/null 2>&1
この特別な場合には、ショートカット構文があります:&>
...または>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
注意:2>&1
存在する場合1>&2
、正しい構文です:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b-今、私はあなたに考えさせます:
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- 詳細情報に興味がある場合
あなたは以下を押すことで良いマニュアルを読むことができます:
man -Len -Pless\ +/^REDIRECTION bash
で バッシュ コンソール ;-)