0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Powershellで名称末尾が半角スペースのフォルダを作ろうとするとハマる

Last updated at Posted at 2025-03-07

結論

環境: 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 なりがエラーを出さずに勝手にスペースを削ったフォルダ名でフォルダを作るのはちょっと予想外の挙動なので、気をつけたほうが良さそうです。

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?