mcpField
P
powershell-shell-detection

powershell-shell-detection

github.com/josiahsiegel開発59207 回インストール19 週間前に更新
リポジトリ

powershell-shell-detection について

Windows のスクリプト開発者向けのシェル検出・互換性ガイドです。PowerShell、Git Bash/MSYS2、WSL の識別を中心に、パス、環境変数、コマンド、自動パス変換の問題を扱います。

主な機能

  1. 01PowerShell、Git Bash、WSL の検出
  2. 02シェル変数とパスの比較
  3. 03Git Bash のパス変換の解説
  4. 04シェル対応スクリプトの作成
  5. 05コマンドとパスの問題の診断

活用シーン

  1. 01スクリプトで実行中のシェルを検出
  2. 02Windows と Bash のパス差異への対応
  3. 03コマンド引数の自動変換の修正
  4. 04シェル間で使えないコマンドの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill powershell-shell-detection

インストール後、Claude Code で/powershell-shell-detectionを入力して読み込まれたか確認します。

詳細

PowerShell シェルの検出とシェル間の互換性

Windows で PowerShell と Git Bash/MSYS2 シェルを見分けるための重要なガイダンスです。シェル固有のパス処理と互換性に関する注意事項も説明します。

シェル検出の優先順位(Windows)

Windows で作業する場合、適切なパス処理とコマンド実行のために、シェル環境を正しく特定することが重要です。

検出順序(信頼性の高い順)
  1. process.env.PSModulePath(PowerShell 固有)
  2. process.env.MSYSTEM(Git Bash/MinGW 固有)
  3. process.env.WSL_DISTRO_NAME(WSL 固有)
  4. uname -s の出力(シェル間で共通、実行が必要)

PowerShell の検出

主な判定指標

PSModulePath(最も信頼性が高い):

# PowerShell detection
if ($env:PSModulePath) {
    Write-Host "Running in PowerShell"
    # PSModulePath contains 3+ paths separated by semicolons
    $env:PSModulePath -split ';'
}

# Check PowerShell version
$PSVersionTable.PSVersion
# Output: 7.5.4 (PowerShell 7) or 5.1.x (Windows PowerShell)

PowerShell 固有の変数:

# These only exist in PowerShell
$PSVersionTable    # Version info
$PSScriptRoot      # Script directory
$PSCommandPath     # Script full path
$IsWindows         # Platform detection (PS 7+)
$IsLinux           # Platform detection (PS 7+)
$IsMacOS           # Platform detection (PS 7+)
スクリプトでのシェル種別の検出
function Get-ShellType {
    if ($PSVersionTable) {
        return "PowerShell $($PSVersionTable.PSVersion)"
    }
    elseif ($env:PSModulePath -and ($env:PSModulePath -split ';').Count -ge 3) {
        return "PowerShell (detected via PSModulePath)"
    }
    else {
        return "Not PowerShell"
    }
}

Get-ShellType

Git Bash / MSYS2 の検出

主な判定指標

MSYSTEM 環境変数(最も信頼性が高い):

# Bash detection in Git Bash/MSYS2
if [ -n "$MSYSTEM" ]; then
    echo "Running in Git Bash/MSYS2: $MSYSTEM"
fi

# MSYSTEM values:
# MINGW64 - Native Windows 64-bit environment
# MINGW32 - Native Windows 32-bit environment
# MSYS    - POSIX-compliant build environment

その他の検出方法:

# Using OSTYPE (Bash-specific)
case "$OSTYPE" in
    msys*)   echo "MSYS/Git Bash" ;;
    cygwin*) echo "Cygwin" ;;
    linux*)  echo "Linux" ;;
    darwin*) echo "macOS" ;;
esac

# Using uname (Most portable)
case "$(uname -s)" in
    MINGW64*) echo "Git Bash 64-bit" ;;
    MINGW32*) echo "Git Bash 32-bit" ;;
    MSYS*)    echo "MSYS" ;;
    CYGWIN*)  echo "Cygwin" ;;
    Linux*)   echo "Linux" ;;
    Darwin*)  echo "macOS" ;;
esac

Windows でのシェル間の互換性

主な違い
項目PowerShellGit Bash/MSYS2
環境変数$env:VARIABLE$VARIABLE
パス区切り文字;(セミコロン):(コロン)
パス形式C:\Windows\System32/c/Windows/System32
ホームディレクトリ$env:USERPROFILE$HOME
一時ディレクトリ$env:TEMP/tmp
コマンド形式Get-ChildItemls(ネイティブコマンド)
エイリアスPowerShell コマンドレットのエイリアスUnix コマンドのエイリアス
パス処理:PowerShell と Git Bash

PowerShell のパス処理:

# Native Windows paths work directly
$path = "C:\Users\John\Documents"
Test-Path $path  # True

# Forward slashes also work in PowerShell 7+
$path = "C:/Users/John/Documents"
Test-Path $path  # True

# Use Join-Path for cross-platform compatibility
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.json"

# Use [System.IO.Path] for advanced scenarios
$fullPath = [System.IO.Path]::Combine($home, "documents", "file.txt")

Git Bash のパス処理:

# Git Bash uses Unix-style paths
path="/c/Users/John/Documents"
test -d "$path" && echo "Directory exists"

# Automatic path conversion (CAUTION)
# Git Bash converts Unix-style paths to Windows-style
# /c/Users → C:\Users (automatic)
# Arguments starting with / may be converted unexpectedly

# Use cygpath for manual conversion
cygpath -u "C:\path"      # → /c/path (Unix format)
cygpath -w "/c/path"      # → C:\path (Windows format)
cygpath -m "/c/path"      # → C:/path (Mixed format)

Git Bash での自動パス変換(重要)

Git Bash/MSYS2 は特定の状況でパスを自動的に変換するため、問題が発生することがあります。

変換が実行される条件
# Leading forward slash triggers conversion
command /foo         # Converts to C:\msys64\foo

# Path lists with colons
export PATH=/foo:/bar  # Converts to C:\msys64\foo;C:\msys64\bar

# Arguments after dashes
command --path=/foo    # Converts to --path=C:\msys64\foo
変換の対象外
# Arguments with equals sign (variable assignments)
VAR=/foo command      # NOT converted

# Drive specifiers
command C:/path       # NOT converted

# Arguments with semicolons (already Windows format)
command "C:\foo;D:\bar"  # NOT converted

# Double slashes (Windows switches)
command //e //s       # NOT converted
パス変換の無効化
# Disable ALL conversion (Git Bash)
export MSYS_NO_PATHCONV=1
command /foo  # Stays as /foo

# Exclude specific patterns (MSYS2)
export MSYS2_ARG_CONV_EXCL="*"           # Exclude everything
export MSYS2_ARG_CONV_EXCL="--dir=;/test"  # Specific prefixes

Windows で PowerShell と Git Bash のどちらを使うか

次の場合は PowerShell を使用します:
  • ✅ Windows 固有のタスク - レジストリ、WMI、Windows サービス
  • ✅ Azure/Microsoft 365 の自動化 - Az、Microsoft.Graph モジュール
  • ✅ モジュールのエコシステム - PSGallery モジュールを活用
  • ✅ オブジェクト指向のパイプライン - 豊富なオブジェクト操作
  • ✅ Windows とのネイティブ統合 - Windows に組み込み
  • ✅ pwsh を使った CI/CD - GitHub Actions、Azure DevOps
  • ✅ クロスプラットフォームのスクリプト作成 - PowerShell 7 は Linux/macOS でも動作

PowerShell の使用例:

# Azure VM management with Az module
Connect-AzAccount
Get-AzVM -ResourceGroupName "Production" |
    Where-Object {$_.PowerState -eq "VM running"} |
    Stop-AzVM -Force
次の場合は Git Bash を使用します:
  • ✅ Unix ツールとの互換性 - sed、awk、grep、find
  • ✅ Git 操作 - ネイティブな Git コマンドライン環境
  • ✅ POSIX スクリプトの実行 - Linux シェルスクリプトの実行
  • ✅ クロスプラットフォームのシェルスクリプト - Linux/macOS の Bash スクリプト
  • ✅ テキスト処理 - Unix のテキストユーティリティ(sed、awk、cut)
  • ✅ 開発ワークフロー - Unix ツールを使った Node.js、Python、Ruby

Git Bash の使用例:

# Git workflow with Unix tools
git log --oneline | grep -i "feature" | awk '{print $1}' |
    xargs git show --stat

シェルを考慮したスクリプトの設計

検出して適応する(PowerShell)
# Detect if running in PowerShell or Git Bash context
function Test-PowerShellContext {
    return ($null -ne $PSVersionTable)
}

# Adapt path handling based on context
function Get-CrossPlatformPath {
    param([string]$Path)

    if (Test-PowerShellContext) {
        # PowerShell: Use Join-Path
        return (Resolve-Path $Path -ErrorAction SilentlyContinue).Path
    }
    else {
        # Non-PowerShell context
        Write-Warning "Not running in PowerShell. Path operations may differ."
        return $Path
    }
}
検出して適応する(Bash)
# Detect shell environment
detect_shell() {
    if [ -n "$MSYSTEM" ]; then
        echo "git-bash"
    elif [ -n "$PSModulePath" ]; then
        echo "powershell"
    elif [ -n "$WSL_DISTRO_NAME" ]; then
        echo "wsl"
    else
        echo "unix"
    fi
}

# Adapt path handling
convert_path() {
    local path="$1"
    local shell_type=$(detect_shell)

    case "$shell_type" in
        git-bash)
            # Convert Windows path to Unix style
            echo "$path" | sed 's|\\|/|g' | sed 's|^\([A-Z]\):|/\L\1|'
            ;;
        *)
            echo "$path"
            ;;
    esac
}

# Usage
shell_type=$(detect_shell)
echo "Running in: $shell_type"

環境変数の比較

よく使われる環境変数
変数PowerShellGit Bash用途
ユーザー名$env:USERNAME$USER現在のユーザー
ホームディレクトリ$env:USERPROFILE$HOMEユーザーのホーム
一時ディレクトリ$env:TEMP/tmp一時ファイル
パス一覧$env:Path(区切り文字 ;)$PATH(区切り文字 :)実行可能ファイルのパス
シェルの検出$env:PSModulePath$MSYSTEMシェル識別子
シェル間での変数アクセス

PowerShell から環境変数にアクセスする場合:

$env:PATH              # Current PATH
$env:PSModulePath      # PowerShell module paths
$env:MSYSTEM           # Would be empty in PowerShell
[Environment]::GetEnvironmentVariable("PATH", "Machine")  # System PATH

Git Bash から環境変数にアクセスする場合:

echo $PATH             # Current PATH
echo $MSYSTEM          # Git Bash: MINGW64, MINGW32, or MSYS
echo $PSModulePath     # Would be empty in pure Bash

実践例

例 1:シェル間でのファイル検索

PowerShell:

# Find files modified in last 7 days
Get-ChildItem -Path "C:\Projects" -Recurse -File |
    Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
    Select-Object FullName, LastWriteTime

Git Bash:

# Same operation in Git Bash
find /c/Projects -type f -mtime -7 -exec ls -lh {} \;
例 2:プロセス管理

PowerShell:

# Stop all Chrome processes
Get-Process chrome -ErrorAction SilentlyContinue | Stop-Process -Force

Git Bash:

# Same operation in Git Bash
ps aux | grep chrome | awk '{print $2}' | xargs kill -9 2>/dev/null
例 3:テキストファイルの処理

PowerShell:

# Extract unique email addresses from logs
Get-Content "logs.txt" |
    Select-String -Pattern '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' |
    ForEach-Object { $_.Matches.Value } |
    Sort-Object -Unique

Git Bash:

# Same operation in Git Bash
grep -oE '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' logs.txt |
    sort -u

シェル間の問題のトラブルシューティング

問題 1:コマンドが見つからない

問題: あるシェルではコマンドが動作するのに、別のシェルでは動作しない

# PowerShell
Get-Process  # Works
# Git Bash
Get-Process  # Command not found

解決策: PowerShell のコマンドレットは Bash には存在しないことを理解してください。ネイティブコマンドを使用するか、Git Bash に PowerShell Core(pwsh)をインストールしてください:

# Run PowerShell from Git Bash
pwsh -Command "Get-Process"
問題 2:パス形式の不一致

問題: シェル間でパスが機能しない

# Git Bash path
/c/Users/John/file.txt  # Works in Bash

# PowerShell
Test-Path "/c/Users/John/file.txt"  # May fail

解決策: cygpath で変換するか、パスを正規化してください:

# Convert to Windows format for PowerShell
win_path=$(cygpath -w "/c/Users/John/file.txt")
pwsh -Command "Test-Path '$win_path'"
問題 3:エイリアスの競合

問題: ls、cd、cat の動作が異なる

# PowerShell
ls  # Actually runs Get-ChildItem
# Git Bash
ls  # Runs native Unix ls command

解決策: PowerShell スクリプトでは完全なコマンドレット名を使用してください:

# Instead of: ls
Get-ChildItem  # Explicit cmdlet name

ベストプラクティスのまとめ

PowerShell スクリプト
  1. ✅ スクリプトからの相対パスには $PSScriptRoot を使用する
  2. ✅ パスには Join-Path または [IO.Path]::Combine() を使用する
  3. ✅ バックスラッシュのハードコードを避ける
  4. ✅ 完全なコマンドレット名を使用する(エイリアスは使わない)
  5. ✅ 対象となるすべてのプラットフォームでテストする
  6. ✅ プラットフォームの判定には $IsWindows、$IsLinux、$IsMacOS を使用する
Git Bash スクリプト
  1. ✅ Git Bash の検出には $MSYSTEM を確認する
  2. ✅ 必要に応じてパスの変換に cygpath を使用する
  3. ✅ 必要に応じて MSYS_NO_PATHCONV=1 を設定し、自動変換を無効にする
  4. ✅ スペースを含むパスは引用符で囲む
  5. ✅ Bash 内では Unix 形式のパス(/c/...)を使用する
  6. ✅ Windows のツールを呼び出す際は、Windows のパスに変換する
シェルをまたぐ開発
  1. ✅ スクリプトが必要とするシェルを明記する
  2. ✅ スクリプトの開始時にシェルを検出する
  3. ✅ 異なるシェルで実行された場合に、わかりやすいエラーメッセージを表示する
  4. ✅ シェル間の互換性を確保するために、ラッパースクリプトの作成を検討する
  5. ✅ 両方をサポートする場合は、PowerShell と Git Bash の両方でテストする

リソース


最終更新日: 2025年10月

コメント