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

PowerShell 7をシェルスクリプトとして使う - ディレクトリとファイルを区別する

【連載】

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

【第146回】PowerShell 7をシェルスクリプトとして使う - ディレクトリとファイルを区別する

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

まず、前回作成したスクリプト「test-d_5.ps1」を見てみよう。次の通りだ。

#!/usr/bin/env pwsh

if (0 -eq $args.Length) {
    Write-Host "usage: test-d_2.ps1 ディレクトリパス"
    exit 1
}

Test-Path -Path $args[0]

引数を1つだけとり、指定されたパスが存在していた場合に「$True」を、存在していない場合に「$False」を返す。引数がなかった場合には使い方を示すメッセージを出力して、「exit 1」で終了する。この場合、「$LASTEXITCODE」には「1」が入ることになる。

このスクリプトは、「指定されたパスが存在するかどうか」しかチェックしていない。対象がディレクトリだろうがファイルだろうが、「$True」として判断してしまう。もともと作りたいと思っているのは、「指定されたディレクトリが存在するかどうか」を調べるスクリプトなので、このままだと問題がある。

ディレクトリとファイルは「Test-Path -PathType」で区別

指定されたパスが存在するかどうかを調べるTest-Pathコマンドレットだが、そのマニュアルを読むと、次のように「-PathType」というパラメータが用意されていることがわかる。

Test-Path (Microsoft.PowerShell.Management) - PowerShell | Microsoft Docs


指定できる値は「Any」「Container」「Leaf」だ。どういった動作になるのか、実際に使って確認してみよう。ショートカットも含めて確認すると、次のようになる。

「Test-Path -PathType」の動作確認サンプル

「Container」はディレクトリを、「Leaf」がファイルを意味していることがわかる。上記サンプルではディレクトリに対するショートカットに対しても使ってみているが、これはファイルとして判定されている。とりあえず、「Test-Path -PathType」を使うことで対象がディレクトリかそうでないかの判断はできそうだ。

ディレクトリだけを判定するように変更

「-PathType Container」を加えたスクリプトが次の「test-d_6.ps1」だ。

#!/usr/bin/env pwsh

if (0 -eq $args.Length) {
    Write-Host "usage: test-d_2.ps1 ディレクトリパス"
    exit 1
}

Test-Path -PathType Container -Path $args[0]

実行すると次のようになる。

実行サンプル

test-d_5.ps1はディレクトリもファイルも存在していれば「$True」としているが、test-d_6.ps1はディレクトリに対してのみ「$True」という判断をしていることがわかる。これで一歩正解へ近づいたわけだ。

「$False」だったときに原因をメッセージを出力

さっきの実行結果をもう一度見てみよう。存在しないパスを指定したときは「$False」になっている。これは正しい動作だ。

存在しないパスは「$False」になる

つまり、パスがファイルだった場合にも「$False」、パスが存在しない場合にも「$False」になる。どちらも挙動は期待通りではあるのだが、せっかくなので、「$False」の理由がわかるようにしたい。そこで、対象がファイルだったのか、それともパスがそもそも存在していなかったのか、条件を切り分けてメッセージを出力するように書き換えたのが次の「test-d_7.ps1」だ。

#!/usr/bin/env pwsh

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
}

実行すると次のようになる。

実行サンプル

「$True」と「$False」が返ってくるのは先ほどと同じだが、「$False」だった場合にはその理由がメッセージとして表示されるようになった。だいぶスクリプトっぽい動きになってきた。

スクリプトが少し複雑になってきたので、コメントを書いておこう。今回の成果物「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
}

ユーティリティ的に自分だけが使うようなスクリプトはそれほど複雑なものにしないほうが使い勝手が良いのだが、シンプルなスクリプトでも最低限のコメントは書いておくとよいと思う。

参考

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

一覧はこちら

連載目次

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

【連載】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用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る