Closed4

PowerShell で ln を使いたい

ピン留めされたアイテム
あきもあきも

ドキュメントが間違っていて混乱したけど直った

以下は記録として残しておく

あきもあきも
Microsoft.PowerShell_profile.ps1
function ln([switch] $s, [string] $filePath, [string] $symlink) {
    if ($s) {
        New-Item -ItemType SymbolicLink -Value $filePath -Name $symlink | Out-Null
    }
    else {
        New-Item -ItemType HardLink -Value $filePath -Name $symlink | Out-Null
    }
}

これで行けると思ったのに、実行したら

ln -s C:\Users\akimo\path\to\original C:\Users\akimo\path\to\target
New-Item: C:\Users\akimo\OneDrive\ドキュメント\PowerShell\Microsoft.PowerShell_profile.ps1:26:3
Line |
  26 |          New-Item -ItemType SymbolicLink -Value $filePath -Name $symli|          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。 : 'C:\Users\akimo\OneDrive\ドキュメント\PowerShell\C:\Users\akimo\path\to\target'

何故か $symlink の前にカレントディレクトリがついてしまって上手くいかない。何が間違ってるのか見当もつかない。

あきもあきも

-Name-Path に変えたら解決した。

Microsoft.PowerShell_profile.ps1
function ln([switch] $s, [string] $filePath, [string] $symlink) {
    if ($s) {
        New-Item -ItemType SymbolicLink -Value $filePath -Path $symlink | Out-Null
    }
    else {
        New-Item -ItemType HardLink -Value $filePath -Path $symlink | Out-Null
    }
}

Microsoft のドキュメントには

この例では、$pshome\profile.ps1 にリンクされる MySymLinkFile.txt という新しいシンボリック リンク ファイルを C:\Temp に作成します。 結果は、3 つの例のいずれでも同じになります。

PowerShell
New-Item -ItemType SymbolicLink -Path C:\Temp -Name MySymLinkFile.txt -Value >$pshome\profile.ps1
New-Item -ItemType SymbolicLink -Path C:\Temp\MySymLinkFile.txt -Value $pshome\profile.ps1
New-Item -ItemType SymbolicLink -Name C:\Temp\MySymLinkFile.txt -Value $pshome\profile.ps1

って書いてあったんだけどなぁ……。

あきもあきも

原因が分かった。
New-Item のドキュメント によると、

Items names passed using the Name parameter are created relative to the value of the Path parameter.

Name パラメータを通して名前を渡すと Path パラメータの値も見てファイルを作成するとのこと。
つまり、前述のドキュメントにあった例を参考にすると、

New-Item -ItemType SymbolicLink -Path C:\Temp -Name MySymLinkFile.txt -Value >$pshome\profile.ps1

これは C:\Temp\MySymLinkFile.txt というシンボリックリンクを作ることになる。要するに PathName が連結されるわけだが、どうやら Path のデフォルトの値がカレントディレクトリになっているらしい。
すっかり

結果は、3 つの例のいずれでも同じになります。

に騙されてしまった……。
相対パスで指定するときは Name、絶対パスでは Path という風に使い分けたらいいのかな? PowerShell の使い方を覚える気が無いからカスタマイズしてるのに、カスタマイズすればするほど PowerShell に詳しくなるのは良いんだか悪いんだか。

このスクラップは2022/01/02にクローズされました