Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2804

リダイレクト操作(>hoge 2>&1等)の自分なりにしっくりきた説明

$
0
0

はじめに

以下のようなbashでのリダイレクト操作に関して、個人的に最もしっくりきた説明を記載します。

cmd > hoge.log
cmd 2> hoge.log
cmd > hoge.log 2>&1
cmd > /dev/null 2>&1
cmd 2>&1 > hoge.log
cmd1 2>&1 | cmd2
cmd1 2>&1 1>/dev/null | cmd2
cmd 3>&2 2>&1 1>&3

以下に記載する内容は「こういうイメージで考えると上記各式の違いを理解できる」、という内容になります。
正確な仕様や詳細な説明は多くの他サイトで説明されていますので、そちらをご覧ください。

ただ私は以下に記載する考え方で、初めて理解が進んだので一つの理解の仕方としてここに記載します。

目次

1.リダイレクトの3つのルール
2.イメージ図
3.各リダイレクト操作の意味を解説
3.1.cmd > hoge.log
3.2.cmd 2> hoge.log
3.3.cmd > hoge.log 2>&1
3.4.cmd > /dev/null 2>&1
3.5.cmd 2>&1 > hoge.log
3.6.cmd1 2>&1 | cmd2
3.7.cmd1 2>&1 1>/dev/null | cmd2
3.8.cmd 3>&2 2>&1 1>&3
まとめ

1.リダイレクトの3つのルール

冒頭で述べた各式の違いを理解するのに覚える必要があるルールは以下3つです。

ルール1 A>hoge (Aの向き先をhogeにする)
ルール2 A>&B (Aの向き先をBが現在指し示す先にする(Bと同じ向き先を向くようにする))
ルール3 リダイレクト記述が複数ある場合左から処理される

※A, Bは数字。Aを省略した場合、A=1とみなされる。

2.イメージ図

リダイレクト操作のイメージ図は以下になります。
スクリーンショット 2020-01-14 14.31.24.png

このイメージ図と3つのルールで、リダイレクト操作を考えます。

3.各リダイレクト操作の意味を解説

では3つのルールとイメージ図を使って、冒頭の各式をひもといていきます。

3.1.cmd > hoge.log

ルール1 A>hoge、Aの向き先をhogeにする。ただしAを省略した場合は1とみなされる。
従って、cmd 1> hoge.logと同じになり、以下のようになります。

スクリーンショット 2020-01-14 14.37.11.png

3.2.cmd 2> hoge.log

ルール1 A>hoge、Aの向き先をhogeにする。
以下のように2の向き先をhoge.logにします。

スクリーンショット 2020-01-14 14.38.33.png

3.3.cmd > hoge.log 2>&1

ルール3、リダイレクト記述が複数ある場合左から処理される、ため、まずはcmd > hoge.logを見ます。
これは、ルール1 A>hoge、Aの向き先をhogeにする(ただしA省略時は1とみなす)、ので以下のようになります。

スクリーンショット 2020-01-14 14.37.11.png

続いて 2>&1。
ルール2 A>&B、Aの向き先をBが現在指し示す先にする。
1が現在指し示す先はhoge.logです。そのため2の向き先をhoge.logにする(以下)。

スクリーンショット 2020-01-14 14.42.50.png

結果として、1(標準出力の内容)も2(標準エラー出力の内容)もhoge.logに出力される。

3.4.cmd > /dev/null 2>&1

/dev/nullにリダイレクトされたものは全て棄てられます。どこにも出力されません。
式の形としては3.3.cmd > hoge.log 2>&1と同じですので、
結果として1(標準出力の内容)も2(標準エラー出力の内容)も棄てられます。

3.5.cmd 2>&1 > hoge.log

これは3.3.cmd > hoge.log 2>&1を逆の順番で書いた場合。
ルール3に従い左から順に処理します。
ルール2 A>&B、Aの向き先をBが現在指し示す先にする、ので2の向き先を1が現在指し示す先にします(以下)。

スクリーンショット 2020-01-14 14.59.06.png

続いて、 > hoge.logを処理します。
ルール1 A>hoge、Aの向き先をhogeにする(ただしA省略時は1とみなす)、ので1>hoge.logは以下のようになります。

スクリーンショット 2020-01-14 14.59.57.png

結果として、1(標準出力の内容)はhoge.logに出力され、2(エラー出力の内容)は標準出力に出力されます。
このように式の順序を変えると全く異なる結果になります。

3.6.cmd1 2>&1 | cmd2

パイプ(|)は、標準出力のみを渡します。そのため標準エラー出力もパイプで渡したい場合このようにします。
ルール2 A>&B、Aの向き先をBが現在指し示す先にする、ので2の向き先を1が現在指し示す先にします(以下)。

スクリーンショット 2020-01-14 14.59.06.png

これで1の内容2の内容両方が標準出力へ出力され、パイプでcmd2へ渡されます。

3.7.cmd1 2>&1 1>/dev/null | cmd2

標準エラー出力だけをパイプで渡したい場合このようにします。
ルール2 A>&B、Aの向き先をBが現在指し示す先にする、ので2の向き先を1が現在指し示す先にします(以下)。

スクリーンショット 2020-01-14 15.20.36.png

続いて1>/dev/nullは、
ルール1 A>hoge、Aの向き先をhogeにする、ので以下になります。

スクリーンショット 2020-01-14 15.19.41.png

結果として、1の内容は棄てられ、2(エラー出力)のみが標準出力に出力され、パイプでcmd2へ渡されます。

3.8.cmd 3>&2 2>&1 1>&3

これは標準出力と標準エラー出力の内容を入れ替えます。
ルール2 A>&B、Aの向き先をBが現在指し示す先にする、およびルール3に従い左から順に処理します(以下)。

スクリーンショット 2020-01-14 15.28.35.png

結果として、2の内容が標準出力へ、1の内容が標準エラー出力へ出力されます。

まとめ

本記事では「冒頭で記載したリダイレクトを含む式」の違いを理解するための考え方(イメージ)を記載しました。

なお正確な仕様やリダイレクトの詳細な説明に関しては、他にたくさん説明されているサイトがあるのでそちらをご参照ください。


Viewing all articles
Browse latest Browse all 2804

Trending Articles