マイナビニュースマイナビ

PowerShell 7をシェルスクリプトとして使う - ストリームの使い分け

【連載】

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

【第147回】PowerShell 7をシェルスクリプトとして使う - ストリームの使い分け

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

前回までの取り組みで、「あるディレクトリのパスが存在しているかどうか」を確認できるようになった。成果物(test-d_8.ps1)は次の通りだ。

#!/usr/bin/env pwsh

# 1つの引数が必要。引数はディレクトリパス。
if (0 -eq $args.Length) {
    Write-Host "usage: test-d_2.ps1 ディレクトリパス"
    exit 1
}

if (Test-Path -PathType Container -Path $args[0]) {
    # 指定されたパスはディレクトリ
    $True
} else {
    # 指定されたパスはディレクトリではない
    if (Test-Path -PathType Leaf -Path $args[0]) {
        # 指定されたパスはファイル
        Write-Host "$args[0]: ファイルです。"
    } else {
        # 指定されたパスは存在しない
        Write-Host "$args[0]: そのようなディレクトリは存在しません。"
    }
    $False
}

今回は、前回追加したメッセージのストリームの調整を行うことにしよう。前回、必要な引数が指定されていない場合と、対象のパスが存在しない場合、対象のパスがディレクトリパスではない場合に、メッセージを出力するようにした。

メッセージの出力には、何も考えずにWrite-Hostコマンドレットを使った。「Write-Host」は「echo」がエイリアスになっており、何かと扱いやすいコマンドレットだからだ。Write-Hostコマンドレットの出力を調べると、次のようにストリーム6で出力されていることがわかる。

Write-Hostはストリーム6を使用

ストリーム6でも良いが、引数がない場合にはどちらかと言えばストリーム2のほうが適切だろう。「$False」になる場合のメッセージは補助的な情報を出していると捉えれば、ストリーム6で良いような気がする。ということで、引数が指定されていない場合のメッセージ出力をストリーム6からストリーム2へ変更しよう。

書き換えと実行

Write-Hostコマンドレットを、Write-Errorコマンドレットに置き換えると、出力先がストリーム6からストリーム2に切り替わる。書き換えた「test-d_9.ps1」は次の通りだ。

#!/usr/bin/env pwsh

# 1つの引数が必要。引数はディレクトリパス。
if (0 -eq $args.Length) {
    Write-Error "usage: test-d_2.ps1 ディレクトリパス"
    exit 1
}

if (Test-Path -PathType Container -Path $args[0]) {
    # 指定されたパスはディレクトリ
    $True
} else {
    # 指定されたパスはディレクトリではない
    if (Test-Path -PathType Leaf -Path $args[0]) {
        # 指定されたパスはファイル
        Write-Host "$args[0]: ファイルです。"
    } else {
        # 指定されたパスは存在しない
        Write-Host "$args[0]: そのようなディレクトリは存在しません。"
    }
    $False
}

動作確認を行うと次のようになる。引数がない場合にはストリーム2、「$False」が返るときのメッセージはストリーム6になっていることを確認できる。

test-d_9.ps1の実行サンプル

これでメッセージの出力がより意図に沿うものになった。

リダイレクトとストリーム

PowerShellではコマンドレットを変更することで出力先のストリームを切り替えるが、UNIXのシェルではリダイレクトを使ってファイルディスクリプタを切り替える。しかし、この方法はPowerShellでは使えない。少なくとも、現在のバージョンでは使えない。

PowerShellのリダイレクトは次のような書式になっている。

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

ストリームはそれぞれ次のような意味を持っている。

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

主な使い方をまとめると次のようになる。

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

ここで注目したいのはリダイレクトである「n>&1」という表記だ。これは「指定したストリームnをストリーム1へリダイレクトする」という意味だが、注目する必要があるのはリダイレクト先としてストリーム1しか指定できないことである。

UNIXのシェルであれば「1>&2」という記述で、標準出力を標準エラー出力へリダイレクトできる。PowerShellでもこの機能が使えれば「echo “メッセージ” 6>&2」といった書き方で、ストリーム2へメッセージを書き込めるのだが、現在のPowerShellではこの機能は使うことができない。今後この書き方がサポートされるかどうかは定かではないが、便利な書き方なのでそのうち追加されるのではと筆者は予測している。コミュニティの反応も含めて、今後の展開を見守りたいところだ。

ただメッセージを出力するだけの処理だが、適切なストリームを使うようにすることで、自分でもスクリプトの内容を整理できるようになる。

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

一覧はこちら

連載目次

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

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

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

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

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で TECH+ の人気記事をお届けします
注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
Slackで始める新しいオフィス様式
Google Workspaceをビジネスで活用する
ニューノーマル時代のオウンドメディア戦略
ミッションステートメント
次世代YouTubeクリエイターの成長戦略
IoTでできることを見つけるための発想トレーニング
教えてカナコさん! これならわかるAI入門
AWSではじめる機械学習 ~サービスを知り、実装を学ぶ~
Kubernetes入門
SAFeでつくる「DXに強い組織」~企業の課題を解決する13のアプローチ~
マイクロサービス時代に活きるフレームワーク Spring WebFlux入門
AWSで作るマイクロサービス
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

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

一覧はこちら

会員登録(無料)

ページの先頭に戻る