1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

バッチの引数にファイルパスを渡すと壊れるのな

Last updated at Posted at 2019-04-15

ファイル名破壊を回避するサブルーチン

以下の バッチサブルーチンは、引数を全てダブルクオーテーションで囲み直し、ファイル名の破壊を防ぐ。

:quote_args
  set __QUOTE_ARGS__=
  setlocal enabledelayedexpansion
  set "ARGS=%* "
  :next
  for %%a in (!ARGS!) do (
    if '%%a' == '"%%~a"' (
      set "BUFF=!BUFF! %%a"
      set "ARGS=!ARGS:*" =!"
      goto next
    )
    for %%b in ("!ARGS: =" "!") do ( 
      set "BUFF=!BUFF! %%b"
      set "ARGS=!ARGS:* =!"
      goto next
    )
  )
  endlocal & call set "__QUOTE_ARGS__=%BUFF:~1%"
  exit /b

使い方はそのまま既存のバッチに埋め込んで簡単に使用できる。

@echo off

rem 既存バッチ全体をサブルーチン化(main)して呼び直す
call :quote_args %*
call :main %__QUOTE_ARGS__%
:main

rem 既存バッチスクリプト本体
~
~
for %%a in (%*) do (
  echo %%a
)
~
~
exit /b

rem 引数処理サブルーチン埋め込み
:quote_args
  set __QUOTE_ARGS__=
~
~

こんな意味不明のコードを埋め込みたくなければ、そのまま外出しの BAT ファイルにして外部ライブラリとして呼び出してもよい。

@echo off

rem 外部ファイルのライブラリとして呼び出す
call .\quote_args.bat %*
call :main %__QUOTE_ARGS__%
:main

rem 既存バッチスクリプト本体
~
~
for %%a in (%*) do (
  echo %%a
)
~
~

既存バッチを編集することさえ避けたいのなら、逆に、ラッパーにして既存バッチを呼び出すことも可能だ。

@echo off

rem 既存 BAT に引数を渡しなおす
call :quote_args %*
call .\legacy.bat %__QUOTE_ARGS__%
exit /b

:quote_args
  set __QUOTE_ARGS__=
~
~

これで、バッチにファイルをDrag & Dropしても常に有効なフルパス名が引き渡せるようになる。

ただし一部使用できない記号(%,!,&,^)がある。

解説

解説はしない、腹が立つので。
Qiitaの皆さんはこういうくだらない事にかかずらってはなりませぬ。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?