サーチ…


構文

  • コマンド</ 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で出力されるものは、プログラムの「結果」とみなされSTDOUTSTDOUTは通常、ファイル記述子1が割り当てられます。

STDERRは、エラーメッセージが表示される場所です。通常、コンソールからプログラムを実行すると、 STDERRが画面に出力され、 STDOUTと区別できなくなりSTDOUTSTDERRは、通常、ファイル記述子2が割り当てられます。

リダイレクトの順序は重要です

command > file 2>&1

両方のファイル( STDOUTSTDERR )をファイルにリダイレクトします。

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

注:内部ファイルディスクリプタのデフォルト設定に0STDIN )のための<

$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c

STDOUTとSTDERRの両方のリダイレクト

01ようなファイル記述子はポインタです。どのファイル記述子がリダイレクトを指しているかを変更します。 >/dev/nullは、 1/dev/null指していることを意味し/dev/null

最初に、 1STDOUT )を/dev/null2STDERR )を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
4.0

これさらに次のように短縮することできます:

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のリダイレクト

2STDERRです。

$ echo_to_stderr 2>/dev/null # echos nothing

定義:

echo_to_stderr"stderr"STDERR書き込むコマンドです

echo_to_stderr () {
    echo stderr >&2
}

$ echo_to_stderr
stderr

追加と切り捨て

切り捨て>

  1. 指定されたファイルが存在しない場合は作成します。
  2. 切り捨て(ファイルの内容を削除する)
  3. ファイルに書き込む
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines

$ cat /tmp/lines
second line

追加>>

  1. 指定されたファイルが存在しない場合は作成します。
  2. ファイルを追加する(ファイルの最後に書き込む)。
# 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のいずれかを必要なものにリダイレクトできます。たとえば、標準出力のみが必要で、標準エラーで出力されるすべてのエラーメッセージを抑制する必要があるとします。それが記述子12を使用するときです。

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"

ネットワークアドレスへのリダイレクト

2.04

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リスナーに送信します



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow