リダイレクト演算子

【連載】

PowerShell Core入門 - 基本コマンドの使い方

【第50回】リダイレクト演算子

[2019/05/10 07:00]後藤大地 ブックマーク ブックマーク

  • サーバ/ストレージ

サーバ/ストレージ

リダイレクト演算子

UNIX系のシェルを扱う方なら、リダイレクトを使ったことがあるだろう。

もっとも簡単なリダイレクトは「>」だ。この記号を使った場合、記号の右側に書いたファイルパスに記号の左側に書いたコマンドの標準出力がリダイレクトされるようになる。ようするにコマンドの出力がファイルに書き込まれるようになる。「>>」だと新規書き込みではなく追記といった処理になる。

PowerShell Coreにもほとんど同じ処理を行うための記号として「リダイレクト演算子」が用意されている。使い方はシェルのリダイレクトとほとんど同じだ。

演算子 内容
> ファイルへ書き込み
>> ファイルへ追記
>&1 ストリームをサクセスストリームへリダイレクト

リダイレクト演算子には次のようにストリーム番号を指定することができる。リダイレクト演算子を指定しなかった場合、デフォルトの値として1が指定されたものとして処理が行われる。

演算子 内容
n> ストリームnをファイルへ書き込み
n>> ストリームnをファイルへ追記
n>&1 ストリームnをストリーム1(サクセスストリーム)へリダイレクト

ストリーム番号には次のようなものが用意されている。シェルの標準入力や標準エラー出力に相当するものだと考えておけばよいと思う。標準出力のファイルディスクリプタは1、標準エラー出力のファイルディスクリプタは2であり、PowerShell Coreのストリーム番号と一致している。故意に同じにしてあるのだと思う。

ストリーム番号 内容
1 サクセスストリーム
2 エラーストリーム
3 ワーニングストリーム
4 冗長ストリーミング
5 デバッグストリーム
6 インフォメーションストリーム
* すべてのストリーム

シェルとPowerShell Coreの大きな違いは、シェルでは1 (標準出力)と2(標準エラー出力)のみを扱うことがほとんどであるのに対して、PowerShell Coreでは1から6までストリームが用意されている点にある。1と2に関してはシェルもPowerShell Coreもほとんど同じだ。ストリーム番号3以上が用意されている点がPowetShell Coreの独自と言える。出力に関して意味ごとにより細かく出力を制御できるようになっていることがわかる。

ストリーム番号とリダイレクト演算子の組み合わせを列挙すると次のようになる。

演算子 内容
> 1>と同じ
>> 1>>と同じ
1> サクセスストリームをファイルへ書き込み
1>> サクセスストリームをファイルへ追加
2> エラーストリームをファイルへ書き込み
2>> エラーストリームをファイルへ追加
2>&1 エラーストリームをサクセスストリームへリダイレクト
3> ワーニングストリームをファイルへ書き込み
3>> ワーニングストリームをファイルへ追加
3>&1 ワーニングストリームをサクセスストリームへリダイレクト
4> 冗長ストリームをファイルへ書き込み
4>> 冗長ストリームをファイルへ追加
4>&1 冗長ストリームをサクセスストリームへリダイレクト
5> デバッグストリームをファイルへ書き込み
5>> デバッグストリームをファイルへ追加
5>&1 デバッグストリームをサクセスストリームへリダイレクト
6> インフォメーションストリームをファイルへ書き込み
6>> インフォメーションストリームをファイルへ追加
6>&1 インフォメーションストリームをサクセスストリームへリダイレクト
*> すべてのストリームをファイルへ書き込み
*>> すべてのストリームをファイルへ追加
*>&1 すべてのストリームをサクセスストリームへリダイレクト

「>」と「>>」に関してはわかりやすいと思うが、「>&1」はちょっとわかりにくいかもしれない。シェルの場合にはシステムコールを使って指定したファイルディスクリプタを標準出力のファイルディスクリプタで上書き……というかコピーする処理に相当するのだが、PowerShell Coreの場合にもほとんど同じ動きをする。PowerShell Coreの場合にはストリームのコピーということになる。

これは例を考えると理解しやすい。「3>&1」といったリダイレクト演算子を指定した場合、ワーニングストリームへの出力がサクセスストリームへの出力に変わる。これはエラーも含めて標準出力に流したいといった場合に利用する。

リダイレクト演算子の使用例

リダイレクト演算子のもっとも基本的な使い方は「>」でサクセスストリーム(標準出力)のリダイレクト、「2>」でエラーストリーム(標準エラー出力)のリダイレクトだろう。シェルやUNIX環境における「/dev/null」のような処理はPowerShell Coreでは「$null」で機能するので、次のような方法で基本的なリダイレクト演算子の実行を確認することができる。

サクセスストリームのリダイレクトを確認

PS /Users/daichi> echo "Hello World" 
Hello World
PS /Users/daichi> echo "Hello World" > $null
PS /Users/daichi> echo "Hello World" 2> $null
Hello World
PS /Users/daichi>

故意にエラーメッセージを表示させれば、次のようにエラーストリームのリダイレクトを確認することができる。

エラーストリームのリダイレクトを確認

PS /Users/daichi> dir C:/Hello
dir : Cannot find drive. A drive with the name 'C' does not exist.
At line:1 char:1
+ dir C:/Hello
+ ~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:String) [Get-ChildItem], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS /Users/daichi> dir C:/Hello > $null
dir : Cannot find drive. A drive with the name 'C' does not exist.
At line:1 char:1
+ dir C:/Hello > $null
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:String) [Get-ChildItem], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS /Users/daichi> dir C:/Hello 2> $null
PS /Users/daichi>

サクセスストリームとエラーストリームの双方に対してメッセージが流れるようにコマンドレットを実行してやると、それぞれ対象だけがリダイレクトされていることがよくわかる。

サクセスストリームとエラーストリームの双方に送られるコマンドレットの結果をリダイレクト

PS /Users/daichi> dir '/', 'C:\'


    Directory: /

Mode                LastWriteTime         Length Name
‐‐‐‐                ‐‐‐‐‐‐‐‐‐‐‐‐‐         ‐‐‐‐‐‐ ‐‐‐‐
d‐r‐‐‐        2019/05/07    15:17                Applications
d‐r‐‐‐        2019/04/06     4:56                bin
d‐r‐‐‐        2018/09/28    23:26                cores
d‐r‐‐‐        2019/04/06     4:58                dev
d‐r‐‐l        2018/09/28    23:23                etc
d‐r‐‐‐        2019/05/07    16:12                home
d‐r‐‐‐        2016/10/03     3:38                Incompatible Software
d‐r‐‐‐        2018/09/29    10:25                Library
d‐r‐‐‐        2019/05/07    16:12                net
d‐r‐‐‐        2018/09/28    23:26                Network
d‐r‐‐‐        2018/09/28    23:26                private
d‐‐‐‐‐        2017/11/28     9:16                root
d‐r‐‐‐        2019/04/06     4:56                sbin
d‐r‐‐‐        2018/09/21     0:05                System
d‐r‐‐l        2018/09/28    23:24                tmp
d‐r‐‐‐        2018/09/28    23:26                Users
d‐r‐‐‐        2018/09/21     0:01                usr
d‐r‐‐l        2018/09/28    23:24                var
d‐r‐‐‐        2019/05/07    17:25                Volumes
d‐r‐‐l        2012/08/14    10:20                ユーザ情報
‐‐r‐‐‐        2018/08/17    20:55            313 installer.failurerequests
dir : Cannot find drive. A drive with the name 'C' does not exist.
At line:1 char:1
+ dir '/', 'C:\'
+ ~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:String) [Get‐ChildItem], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand


PS /Users/daichi>

サクセスストリームがリダイレクトされ、エラーストリームだけが表示されている

PS /Users/daichi> dir '/', 'C:\' > $null  
dir : Cannot find drive. A drive with the name 'C' does not exist.
At line:1 char:1
+ dir '/', 'C:\' > $null
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:String) [Get-ChildItem], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS /Users/daichi>

エラーストリームがリダイレクトされ、サクセスストリームだけが表示されている

PS /Users/daichi> dir '/', 'C:\' 2> $null


    Directory: /

Mode                LastWriteTime         Length Name
‐‐‐‐                ‐‐‐‐‐‐‐‐‐‐‐‐‐         ‐‐‐‐‐‐ ‐‐‐‐
d‐r‐‐‐        2019/05/07    15:17                Applications
d‐r‐‐‐        2019/04/06     4:56                bin
d‐r‐‐‐        2018/09/28    23:26                cores
d‐r‐‐‐        2019/04/06     4:58                dev
d‐r‐‐l        2018/09/28    23:23                etc
d‐r‐‐‐        2019/05/07    16:12                home
d‐r‐‐‐        2016/10/03     3:38                Incompatible Software
d‐r‐‐‐        2018/09/29    10:25                Library
d‐r‐‐‐        2019/05/07    16:12                net
d‐r‐‐‐        2018/09/28    23:26                Network
d‐r‐‐‐        2018/09/28    23:26                private
d‐‐‐‐‐        2017/11/28     9:16                root
d‐r‐‐‐        2019/04/06     4:56                sbin
d‐r‐‐‐        2018/09/21     0:05                System
d‐r‐‐l        2018/09/28    23:24                tmp
d‐r‐‐‐        2018/09/28    23:26                Users
d‐r‐‐‐        2018/09/21     0:01                usr
d‐r‐‐l        2018/09/28    23:24                var
d‐r‐‐‐        2019/05/07    17:25                Volumes
d‐r‐‐l        2012/08/14    10:20                ユーザ情報
‐‐r‐‐‐        2018/08/17    20:55            313 installer.failurerequests

PS /Users/daichi>

Write-Warningコマンドレットを使用するとワーニングストリームに対してメッセージを送ることができ、次のように「3>」でワーニングストリームだけがリダイレクトできることを確認できる。「*>」はすべてのストリームに対して適用されるので、ワーニングストリームについてもリダイレクトを確認できる。

Write-Warningコマンドレットでワーニングストリームに対してリダイレクトを送信

PS /Users/daichi> Write-Warning 'Hello'   
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' > $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' 1> $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' 2> $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' 3> $null
PS /Users/daichi> Write-Warning 'Hello' 4> $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' 5> $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' 6> $null
WARNING: Hello
PS /Users/daichi> Write-Warning 'Hello' *> $null
PS /Users/daichi>

次のような書き方をすると、複数の種類のストリームに対してメッセージを送信し、それらをリダイレクトする方法を試すことができる。書き方としては「3>&1 6>&1 > $null」に注目しておきたい。

複数のストリームに対してメッセージを出力し、それらをリダイレクトするサンプル

PS /Users/daichi> &{ Write-Warning 'Hello'; Write-Information 'World'; }
WARNING: Hello
PS /Users/daichi> &{ Write-Warning 'Hello'; Write-Information 'World'; } 6>&1
WARNING: Hello
World
PS /Users/daichi> &{ Write-Warning 'Hello'; Write-Information 'World'; } 3>&1 6>&1
WARNING: Hello
World
PS /Users/daichi> &{ Write-Warning 'Hello'; Write-Information 'World'; } 3>&1 6>&1 > $null
PS /Users/daichi>

「3>&1 6>&1 > $null」で、まずワーニングストリームがサクセスストリームとなり、次にインフォメーションストリームがサクセスストリームになっている。最後の「> $null」でサクセスストリームが「$null」にリダイレクトされるので、すべての出力が消えることになる。こうした書き方はシェルやシェルスクリプトではよく用いられるが、PowerShell Coreでも同じような書き方を行うことができる。

ファイルへのリダイレクトはリダイレクト演算子を使わずとも、Out-Fileコマンドレットを使っても行うことができる。しかし、リダイレクト演算子で同じことが可能で、シェルやシェルスクリプトと書き方も同じなので、こちらを覚えておいた方が便利だろう。

参考資料

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】RPA入門 - ツールで学ぶ活用シーン

【連載】RPA入門 - ツールで学ぶ活用シーン

AIには、ルールベース、機械学習、深層学習(ディープラーニング)の3つのレベルがあり、レベルが上がるに連れてより高度な人工知能を実現しますが、AIのスピンオフという位置付けで、Digital Labor(仮想知的労働者)によるホワイトカラー業務の自動化を実現するRPAが注目されています。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
知りたい! カナコさん 皆で話そうAIのコト
教えてカナコさん! これならわかるAI入門
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
ソフトウェア開発自動化入門
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る