2017-01-20 9 views
2

powershellスクリプト内でファイルパスの文字列を生成したい。私はWindowsとMacの両方でこれを動作させたい。PowershellがWindowsとUnixで正しくファイルパスを生成する

コードはパスのようなウィンドウにハードコードされた瞬間に( "\" - >窓、 "/" - > UNIX): $templatep="$CoreRoot\templates\$serviceName"

私はこれを変更: $templatep= Join-Path $CoreRoot "templates" $serviceName そして、それは、Macで動作しますPowershell 6.0で。これはちょうど私のマックで働いている理由

$templatep= Join-Path $CoreRoot -ChildPath "templates" | Join-Path -ChildPath $serviceName

任意のアイデア:それは私がこのような何かをしなければならないのPowershell 4と私のWindowsサーバでは動作しませんか?これはPowerShell 5または6の新機能ですか? 複数のJoin-Pathをパイプする必要がありません。これを行うより良い方法はありますか?

ありがとうございます!

+2

私の知る限り、Join-Pathは2つのパスしか取ることができません。別のジョインにパイプを張ったり、.Netの '[io.path] :: combine()'メソッドを使って、私が知っている2つの回避策です。 – BenH

答えて

3

まず、.NETフレームワークを使用して回避策

[IO.Path]::Combine('a', 'b', 'c') 

これは、Windows上でUnix上a/b/c、そしてa\b\cもたらし、そして便利なパスコンポーネントの任意のの数をサポートしています。

注:Join-PathはどのPowerShellドライブプロバイダのパスで動作するように設計されたのに対し、

  • この回避策は、唯一ファイルシステムパスのためです。

  • のいずれかの成分が無視されているため、\(Windows)または/最初開始以外のコンポーネント(UNIX)ことを確認してください。たとえば、Windowsの場合:
    [IO.Path]::Combine('\a', '\b', 'c') # -> '\b\c' - '\a' is ignored(!)
    Join-Pathではありません。はこの現象を示します。詳細はthis answer私のを参照してください。パイプラインとシークエンシングに代替Join-Path呼び出しとして

することができます単に使用(...)(部分式):

Join-Path a (Join-Path b c) # -> 'a\b\c' (on Windows) 

私はための説明なしを持っています行動の違い; Join-Path -?で表示される構文はWindows PowerShellのv5.1.14393.693PowerShellのコアv6.0.0-alpha.14(偶発的パラメータは省略)のように、両方のプラットフォームで同じです。この構文に基づいて

Join-Path [-Path] <String[]> [-ChildPath] <String> ... 

呼び出しJoin-Path a b cなるはずです構文エラーにあります。これは実際にはWindowsA positional parameter cannot be found that accepts argument 'c')で起こりますが、Unixプラットフォームでは起こりません。 [1]

Join-Pathがあまりにもパスコンポーネント、そしてそれは、既にWindows PowerShellでの今後の変化におそらくPowerShellのコアでポイントを働くという事実の任意の数で働いていた場合が、それは確かに便利だろう、と述べたこと。 [-Path] <String[]>アレイパラメータであっても、その目的は、単一の出力経路の複数の子パス成分を受け入れるが、複数親子経路対の接合可能ではないこと

注意。例えば:それはおそらく賢明ではないにもかかわら

$ Join-Path a,b c # same as: Join-Path -Path a,b -ChildPath c 
a\c 
b\c 

は最後に、あなたは、多くの場合、多くのWindows API関数のためだけでなく、ハードコーディング/両方プラットフォーム上のパスの区切りとしてで逃げることができますPowerShellの独自のコマンドレットは\/を同義語として受け入れるので、
しかし、すべてのユーティリティがこのように動作するわけではないので、プラットフォームに適したセパレータを使用するのが一般的に安全です。例えば

、Windows上だけで罰金以下の作品:

Get-Item c:/windows/system32 # same as: Get-Item c:\windows\system32 

[1]厳密に言えば、それはプラットフォームが、PowerShellの版についてではありません。Join-Path a b c作品にマルチプラットフォームのPowerShellコアエディション(Windowsの場合でも) - WindowsネイティブではなくWindows PowerShellエディションv5.1以降)。つまり、PowerShellコアは通常、Unixプラットフォームでのみ使用されます。

+1

答えに感謝します。私は[IO.Path] :: Combineの回避策に行きます –