結論
環境: Windows 11 24H2 + Powershell ver. 7.5
Powershellの mkdir
コマンドレット、 New-Item
コマンドレットでフォルダを作成する際、指定したフォルダ名の末尾に半角スペースがあっても、 エラーは出ず、こっそりと半角スペースが削除されます 。
すなわち、mkdir "test "
としても、実際には "test" というフォルダが作成されてしまします。
思わぬバグの原因になるので、コマンドレットにわたす前に半角スペースを削ったほうが安全そうです。
詳細
フォルダを作る例
$hoge = "test " # testの後に半角スペースがある。全部で5文字のはず。
#実際は$hogeにはユーザ・ファイルからの入力が入りますが…。
mkdir $hoge
[ C:\test ](˘ω˘)> $hoge ="test "
[ C:\test ](˘ω˘)> mkdir $hoge
Directory: C:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2025/03/08 2:04 test
上記のコードを実行すると、以上の結果になります。Name欄がどうも4文字しかないようにみえるので、確かめてみましょう。
[ C:\test ](˘ω˘)> (Get-Item test).Name.Length
4
そう、4文字しかありません。引数で渡した$hoge
の末尾にあったはずのスペースはしれっと無視されて、 test だけがフォルダ名になっています。
コードは省略しますが、New-Itemコマンドレットを使った場合も同じ挙動となります。
ハマる例
上記の mkdir の仕様を前提とすると、以下のようなコードが想定外の挙動を示します。
$hoge ="test "
<#何かの処理
・・・#>
mkdir $hoge #変数で指定されたフォルダを作って
Set-Content -LiteralPath "$hoge/test.txt" -Value "hoge" #指定されたフォルダ内にファイルを出力する
[ C:\test ](˘ω˘)> $hoge ="test "
>> mkdir $hoge
>> Set-Content -LiteralPath "$hoge/test.txt" -Value "hoge"
Directory: C:\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2025/03/08 2:12 test
Set-Content:
Line |
3 | Set-Content -LiteralPath "$hoge/test.txt" -Value "hoge"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Could not find a part of the path 'C:\test\test \test.txt'.
上記のコードを実行すると、出力先パスがないとのエラーが出て怒られてしまいました。
エラーのCould not find a part of the path 'C:\test\test \test.txt'
との文言にあるとおり、 "test " (半角スペースあり)というフォルダが存在しないと言われています。
実際に作成されたフォルダは "test" (半角スペースなし)なので当然のエラーですが、気づかないとハマりました。
Test-Pathも信じられないこと
さらに、引数で指示したとおりのフォルダが作成されているか、Test-Path
コマンドレットで調べてみても、無駄です。
$hoge = "test "
Test-Path $hoge
[ C:\test ](˘ω˘)> Test-Path $hoge
True
そう、 Test-Pathコマンドレットも末尾のスペースを消してから存在判定をするので、"test"があるとして、Trueを返してくるのです 。
したがって、変数で受け取ったフォルダ名については、Test-Path
コマンドレットで存在を確認しても、そのまま当該フォルダ内にファイルを保存できるかは不明、ということになります。
安全な対応
$hoge ="test "
<#何かの処理
・・・#>
$hoge = $hoge -replace "\s+$", "" #末尾の半角スペースを削除してから進む
mkdir $hoge #変数で指定されたフォルダを作って
Set-Content -LiteralPath "$hoge/test.txt" -Value "hoge" #指定されたフォルダ内にファイルを出力する
上記のコードを改変し、こうやってmkdir
に渡す前に末尾の半角スペースを削除してやると安全かと思います。
Windowsの仕様上、フォルダ名の末尾をスペースにすべきでないこと
なお、Windowsの仕様として、
ファイルやディレクトリの名前の末尾をスペースまたはピリオドにしないでください。 基となるファイル システムがこのような名前をサポートしているとしても、Windows のシェルとユーザー インターフェイスではサポートされません。
と明記されているので(ファイル、パス、名前空間の名前付け)、フォルダ名の末尾に半角スペースをつけるべきでないことは明らかです。
ただ、 mkdirなり New-Item なりがエラーを出さずに勝手にスペースを削ったフォルダ名でフォルダを作るのはちょっと予想外の挙動なので、気をつけたほうが良さそうです。
以上。