サーチ…
構文
- コマンド</ path / to / file#標準入力をファイルにリダイレクトする
- command> / path / to / file#標準出力をflieにリダイレクトする
- コマンドfile_descriptor> / path / to / file#file_descriptorの出力をファイルにリダイレクトする
- command>&file_descriptor#出力をfile_descriptorにリダイレクトする
- コマンドfile_descriptor>&another_file_descriptor#file_descriptorをanother_file_descriptorにリダイレクトする
- command <&file_descriptor#file_descriptorを標準入力にリダイレクトする
- コマンド&> / path / to / file#標準出力と標準エラーをファイルにリダイレクトする
パラメーター
パラメータ | 詳細 |
---|---|
内部ファイル記述子 | 整数です。 |
方向 | > 、 < または<> いずれか |
外部ファイル記述子またはパス | ファイル記述子またはパスの後には& 続きます。 |
備考
UNIXコンソールプログラムには、入力ファイルと2つの出力ファイル(入出力ストリーム、およびデバイスはOSによってファイルとして扱われます)があります。これらは通常それぞれキーボードと画面ですが、それらの一部またはすべてをリダイレクトできますファイルまたは他のプログラムから来る - または行く - 。
STDIN
は標準入力であり、プログラムが対話型入力を受け取る方法です。 STDIN
は、通常、ファイル記述子0が割り当てられます。
STDOUT
は標準出力です。 STDOUT
で出力されるものは、プログラムの「結果」とみなされSTDOUT
。 STDOUT
は通常、ファイル記述子1が割り当てられます。
STDERR
は、エラーメッセージが表示される場所です。通常、コンソールからプログラムを実行すると、 STDERR
が画面に出力され、 STDOUT
と区別できなくなりSTDOUT
。 STDERR
は、通常、ファイル記述子2が割り当てられます。
リダイレクトの順序は重要です
command > file 2>&1
両方のファイル( STDOUT
とSTDERR
)をファイルにリダイレクトします。
command 2>&1 > file
ファイルディスクリプタ2がファイルディスクリプタ1(ファイルディスクリプタ1が評価されたときにファイルfile
ではない)にポイントされたファイルにリダイレクトされるため、 STDOUT
のみをリダイレクトします。
パイプラインの各コマンドは、それぞれ新しいプロセスであるため、独自のSTDERR
(およびSTDOUT
)を持っています。これにより、リダイレクトがパイプライン全体に影響を及ぼすことが予想される場合は、驚くべき結果が得られます。たとえば、次のコマンド(読みやすくするためにラップされています):
$ python -c 'import sys;print >> sys.stderr, "Python error!"' \
| cut -f1 2>> error.log
"Python error!"と表示されます。ログファイルではなくコンソールに送信します。代わりに、キャプチャするコマンドにエラーを添付します。
$ python -c 'import sys;print >> sys.stderr, "Python error!"' 2>> error.log \
| cut -f1
標準出力のリダイレクト
>
現在のコマンドの標準出力(別名STDOUT
)をファイルまたは別のディスクリプタにリダイレクトします。
これらの例では、 ls
コマンドの出力をfile.txt
ファイルに書き込みます
ls >file.txt
> file.txt ls
ターゲットファイルが存在しない場合は作成され、そうでない場合はこのファイルが切り捨てられます。
デフォルトのリダイレクト記述子は標準出力です。指定されていない場合は1
なります。このコマンドは、標準出力が明示的に示されている前述の例と同等です。
ls 1>file.txt
注:リダイレクションは、実行されたコマンドではなく、実行されたシェルによって初期化されるため、コマンドの実行前に実行されます。
STDINのリダイレクト
<
その右の引数から読み込み、その左の引数に書き込みます。
ファイルを書き込むにはSTDIN
我々は読んでください/tmp/a_file
とに書き込む STDIN
すなわち0</tmp/a_file
注:内部ファイルディスクリプタのデフォルト設定に0
( STDIN
)のための<
$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c
STDOUTとSTDERRの両方のリダイレクト
0
や1
ようなファイル記述子はポインタです。どのファイル記述子がリダイレクトを指しているかを変更します。 >/dev/null
は、 1
が/dev/null
指していることを意味し/dev/null
。
最初に、 1
( STDOUT
)を/dev/null
、 2
( STDERR
)を1
します。
# STDERR is redirect to STDOUT: redirected to /dev/null,
# effectually redirecting both STDERR and STDOUT to /dev/null
echo 'hello' > /dev/null 2>&1
これはさらに次のように短縮することができます:
echo 'hello' &> /dev/null
しかし、POSIXと競合するためにシェルの互換性が懸念される場合、この形式は生産上望ましくない可能性があります。この機能を持たないシェルでは、解析のあいまいさが発生します。
# Actual code
echo 'hello' &> /dev/null
echo 'hello' &> /dev/null 'goodbye'
# Desired behavior
echo 'hello' > /dev/null 2>&1
echo 'hello' 'goodbye' > /dev/null 2>&1
# Actual behavior
echo 'hello' &
echo 'hello' & goodbye > /dev/null
注意: &>
は、BashとZshの両方で必要に応じて動作することが知られています。
STDERRのリダイレクト
2
はSTDERR
です。
$ echo_to_stderr 2>/dev/null # echos nothing
定義:
echo_to_stderr
は"stderr"
をSTDERR
書き込むコマンドです
echo_to_stderr () {
echo stderr >&2
}
$ echo_to_stderr
stderr
追加と切り捨て
切り捨て>
- 指定されたファイルが存在しない場合は作成します。
- 切り捨て(ファイルの内容を削除する)
- ファイルに書き込む
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines
$ cat /tmp/lines
second line
追加>>
- 指定されたファイルが存在しない場合は作成します。
- ファイルを追加する(ファイルの最後に書き込む)。
# Overwrite existing file
$ echo "first line" > /tmp/lines
# Append a second line
$ echo "second line" >> /tmp/lines
$ cat /tmp/lines
first line
second line
STDIN、STDOUT、STDERRの説明
コマンドには1つの入力(STDIN)と2種類の出力、標準出力(STDOUT)と標準エラー(STDERR)があります。
例えば:
STDIN
root@server~# read
Type some text here
標準入力は、プログラムに入力を提供するために使用されます。 (ここでは、STDINからの行を読み込むために組み込みのread
を使用しています)。
STDOUT
root@server~# ls file
file
標準出力は、通常、コマンドの「通常の」出力に使用されます。たとえば、 ls
はファイルをリストするので、ファイルはSTDOUTに送られます。
STDERR
root@server~# ls anotherfile
ls: cannot access 'anotherfile': No such file or directory
標準エラーは、エラーメッセージに(名前が示すように)使用されます。このメッセージはファイルのリストではないため、STDERRに送信されます。
STDIN、STDOUT、STDERRは3つの標準ストリームです。それらは名前ではなく数字でシェルに識別されます。
0 =標準
1 =標準出力
2 =標準誤差
デフォルトでは、STDINはキーボードに接続されており、STDOUTとSTDERRの両方が端末に表示されます。ただし、STDOUTまたはSTDERRのいずれかを必要なものにリダイレクトできます。たとえば、標準出力のみが必要で、標準エラーで出力されるすべてのエラーメッセージを抑制する必要があるとします。それが記述子1
と2
を使用するときです。
STDERRを/ dev / nullにリダイレクトする
前の例を見てみると、
root@server~# ls anotherfile 2>/dev/null
root@server~#
この場合、STDERRがあれば、それは/ dev / null(それに置かれたものを無視する特別なファイル)にリダイレクトされるので、シェルでエラー出力を得ることはありません。
複数のコマンドを同じファイルにリダイレクトする
{
echo "contents of home directory"
ls ~
} > output.txt
名前付きパイプの使用
1つのプログラムで何かを出力し、それを別のプログラムに入力することもできますが、標準のパイプは使用できないことがあります。
ls -l | grep ".log"
あなたは単に一時ファイルに書き込むことができます:
touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt
これはほとんどのアプリケーションでうまく動作しますが、 tempFile
動作を知る人は誰もいません。そのディレクトリにls -l
の出力が含まれていると、誰かが削除する可能性があります。これは、名前付きパイプが動作する場所です。
mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe
myPipe
は技術的にはファイルです(すべてLinux上にあります)ので、パイプを作成した空のディレクトリでls -l
を実行しましょう:
mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l
出力は次のとおりです。
prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe
パーミッションの最初の文字がファイルではなくパイプとしてリストされていることに注目してください。
今、何かクールなことをしよう。
1つの端末を開き、ディレクトリを書き留めておくか(またはクリーンアップが容易なように作成する)、パイプを作ります。
mkfifo myPipe
さあパイプに何かを入れましょう。
echo "Hello from the other side" > myPipe
これはハングアップすることに気づくでしょう、パイプの反対側はまだ閉じています。パイプの反対側を開き、そのものを通しましょう。
別のターミナルを開いて、パイプが入っているディレクトリに移動します(または、パイプが分かっている場合はパイプに追加します)。
cat < myPipe
hello from the other side
が出力さhello from the other side
後、第1ターミナルのプログラムが終了し、第2ターミナルのプログラムも終了することがわかります。
今度は逆のコマンドを実行してください。 cat < myPipe
、それに何かをエコーします。それは何かを取得する必要があることを知っているので、プログラムが終了する前にパイプに何かが置かれるまでプログラムが待機するため、まだ動作します。
名前付きパイプは、端末間またはプログラム間で情報を移動するのに便利です。
パイプは小さいです。一度いっぱいになると、ライターはコンテンツを読み取る人がいるまでブロックします。したがって、リーダーやライターを異なる端末で実行するか、バックグラウンドでどちらかを実行する必要があります。
ls -l /tmp > myPipe &
cat < myPipe
名前付きパイプを使用したその他の例:
例1 - 同じ端末/同じシェル上のすべてのコマンド
$ { ls -l && cat file3; } >mypipe & $ cat <mypipe # Output: Prints ls -l data and then prints file3 contents on screen
例2 - 同じ端末/同じシェル上のすべてのコマンド
$ ls -l >mypipe & $ cat file3 >mypipe & $ cat <mypipe #Output: This prints on screen the contents of mypipe.
file3
最初の内容が表示された後、ls -l
データが表示されます(LIFO設定)。例3 - 同じ端末/同じシェル上のすべてのコマンド
$ { pipedata=$(<mypipe) && echo "$pipedata"; } & $ ls >mypipe # Output: Prints the output of ls directly on screen
変数ことを心
$pipedata
使用するので、メインターミナル/メインシェルでの使用のために利用できない&
サブシェルを起動すると、$pipedata
このサブシェルでのみ利用可能でした。例4 - 同じ端末/同じシェル上のすべてのコマンド
$ export pipedata $ pipedata=$(<mypipe) & $ ls -l *.sh >mypipe $ echo "$pipedata" #Output : Prints correctly the contents of mypipe
これは、変数のエクスポート宣言のためにメインシェルに
$pipedata
変数の値を正しく表示します。メインシェル/メインシェルは、バックグラウンドシェル(&
)の呼び出しのためにハングしません。
エラーメッセージをstderrに出力する
エラーメッセージは、一般に、デバッグ目的または豊富なユーザーエクスペリエンスを提供するためにスクリプトに含まれています。単に次のようなエラーメッセージを書いてください:
cmd || echo 'cmd failed'
単純なケースではうまくいくかもしれませんが、通常の方法ではありません。この例では、エラーメッセージは、エラーと正常出力の両方をstdout
混合することによって、スクリプトの実際の出力を汚染します。
要するに、エラーメッセージはstdout
ではなくstderr
stdout
ます。それはかなり単純です:
cmd || echo 'cmd failed' >/dev/stderr
もう一つの例:
if cmd; then
echo 'success'
else
echo 'cmd failed' >/dev/stderr
fi
上記の例では、成功メッセージはstdout
され、エラーメッセージはstderr
されます。
エラーメッセージを出力するより良い方法は、関数を定義することです:
err(){
echo "E: $*" >>/dev/stderr
}
今、エラーを出力する必要があるとき:
err "My error message"
ネットワークアドレスへのリダイレクト
Bashはいくつかのパスを特別なものとして扱い、 /dev/{udp|tcp}/host/port
書き込むことでネットワーク通信を行うことができ/dev/{udp|tcp}/host/port
。 Bashはリッスンサーバーを設定することはできませんが、接続を開始することができ、TCPは少なくとも結果を読み取ることができます。
たとえば、単純なWebリクエストを送信するには、次のようにします。
exec 3</dev/tcp/www.google.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3
www.google.com
のデフォルトWebページの結果はstdout
されます。
同様に
printf 'HI\n' >/dev/udp/192.168.1.1/6666
HI\n
を含むUDPメッセージを192.168.1.1:6666
リスナーに送信します