jordan_bethの日記: del コマンドの腐った仕様 16
とあるバッチスクリプトをコーディング中なのだが、その終了処理で、使用したテンポラリファイルを削除する次の一文があったんだ。
del /f /s /q "%FILENAMEVAR%" > NUL 2>&1
「これならバッチファイル実行中に確認プロンプトやらエラーやら表示しないぜ」なんて得意になってたわけだ。で、ある程度出来上がって実行していると、カレントディレクトリのファイルが消えていく…。運の悪いことにテスト実行はスクリプトがおいてあるディレクトリ。いくつかスクリプトを仕上げていたんだが、これが全部なくなっていた…
なんとか削除ファイル復活ソフトを使って一つだけスクリプトを救出、調べてみたら、上の del 文が問題だった。ヘルプ出力時にはメインコードをすっ飛ばして(%FILENAMEVAR%を設定せずに)終了処理を行なっていた。
del /f /s /q "" > NUL 2>&1
が実行されていたわけだ(しかも確認プロンプト、エラーメッセージなしで)。それでも、それはコーディング中想定していた。「空文字指定でも大丈夫だしぃぃい~~」
しかし、マイクロソフトの実装は俺の予想を遙かに超える、超異次元的なものだった。コマンドプロンプトで空文字指定の del コマンドを実行してみる。
C:\Documents and Settings\foo>del ""
C:\Documents and Settings\foo\*、よろしいですか (Y/N)?
( ゚д゚)
(つд⊂)ゴシゴシ
( ゚д゚)
Σ(゚д゚lll)ガーン
工工エエエエエ(´Д`)エエエエエ工工
マイクロソフト的解釈によると、空文字ファイル=ワイルドカード、となってしまうのかぁぁぁぁ
ふざけるなァァ俺の3日間を返せーーーー
(まー XP は10年前のOSだしなー と思って 7 でやっても同じだった .....)
よくある(あった) rm -rf / のトラップに引っかかってしまった気分だ。しかもトラップに引っかかってしまった相手は信頼すべきマイクロソフトという巨大企業。
ということで、こんな夜更け、というか夜明けに(しかも GW なのに)スラドで日記を書いて、憂さ晴らしをしてみる。
#できりゃ Python でやりたかったけど、どうしても Pure DOSバッチじゃないといかん案件だったんだよな(TдT)
re:空文字ファイル=ワイルドカード (スコア:2)
del コマンドは、ダブルクォーテーション1キャラクタでもって、
アスタリスク相当のワイルドカードとして扱っているように見えます。
ひょっとして、シェルが悪者か? と思い、
他のコマンドでも試してみましたが、del コマンド以外では、
同様の動作は確認できませんでした。
// win xp sp2
Re:空文字ファイル=ワイルドカード (スコア:1)
「悪意のある、ソフトウェアの削除ツール」ってやつですね。
こんなふうにすれば (スコア:1)
IF EXIST "%FILENAMEVAR%" del /f /s /q "%FILENAMEVAR%" > NUL 2>&1
みたいにすればだいじょうぶなのでは?
Re:こんなふうにすれば (スコア:1)
いやまぁ、原因がわかってればそうなんですが、今までの経験上(bash, perl, pythonなど)、空文字指定でファイルが削除されるなんて思ってもいなかったわけで。
ヘルプ処理でメインコードが実行されていなくても、delさんは華麗にスルーしてくれる、と信じて疑わなかったわけです。だからこそ強制削除&出力廃棄していたんで....
ん? 俺、今何か言った?
Re:こんなふうにすれば (スコア:1)
まあ、なんて言うか、いまどきcmd.exeでもなかろうよ。PowerShellを使うべき場面だろうね。条件が許さなければ仕方ないけど。
Re: (スコア:0)
まあ、なんて言うか、いまどきcmd.exeでもなかろうよ。PowerShellを使うべき場面だろうね。条件が許さなければ仕方ないけど。
おまえはなにを言っているんだ?
Remove-Itemに空文字食わせたって、エラーで死ぬだけじゃねーか?
そもそも他の処理系と同じようにスルーしてりゃ問題ないのに
勝手に変な解釈して、いつもいつも大きなお世話をしてくれるMSの処理系が問題の根本なんだよ
CMDからPowerShellに代えようがそれは何ひとつ変わらない
# MSの処理系はAPIひとつに至るまで未定義の動作が多すぎる
# しかも「未定義=デフォルト」じゃないから、ある日突然MSがデフォルトの動作を決めて
# それまで「未定義=デフォルト」だと仮定していた全てに問題が起きる
# C/C++のようにそれが未定義ならちゃんと、「 ~な時の動作は未定義である」と書いておいてくれなきゃ困るわ >>>>>MS
Re:こんなふうにすれば (スコア:1)
Remove-Itemに空文字食わせたって、エラーで死ぬだけじゃねーか?
それでいいじゃない。少なくとも、今回のような悲劇は無かっただろ?
そもそも他の処理系と同じようにスルーしてりゃ問題ないのに
それは思想の差。すべての処理系が同じ思想で設計される必要は無い。君の思想だけが正しいわけでもない。
CMDからPowerShellに代えようがそれは何ひとつ変わらない
それはウソ。少なくとも今回のような場合の結果は違うんだから。
いまどきCMD.exeもVBScriptもJScriptも使おうとは思わないけど、PowerShellはそう悪くないよ。配列指向を理解するのに時間はかかるかも知れないけど。
例えば、今回のようなケースであれば、次を参考にコーディングすればいいよ。
これなら、空列を渡してもエラーにはならない。まあ、空文字列を渡しちゃうとエラーになるけどね。
要するに、これが思想の差。他の処理系とは違うけど、悪かぁないだろ? こういう処理系があってもいいんじゃない? いろんなものがあった方が、世の中楽しいだろ?
あ、もちろんPowerShellにもエラー処理構文は準備されているから、それを使ってもいいと思うよ。
Re:こんなふうにすれば (スコア:1)
こう言う方法もあるよ。
しかし、こんな風にはできない。
まあ、これが良い設計か、って言うと疑問だけどね。
Re: (スコア:0)
まあ、なんて言うか、いまどきcmd.exeでもなかろうよ。PowerShellを使うべき場面だろうね。条件が許さなければ仕方ないけど。
他人に提供するものだと素のOS標準で使えるものっていう条件がついたりするんですよね。
自分でしか使わないなら、間違いなくbashで組むけど。
Re:こんなふうにすれば (スコア:1)
他人に提供するものだと素のOS標準で使えるものっていう条件がついたりするんですよね。
そうだね。元の話はXPだから、標準搭載ではないね。
でも、Windows 7・Windows Server 2008(無印)以降には標準搭載だよ。
自分でしか使わないなら、間違いなくbashで組むけど。
Bashは悪くない。Ryo.F自身、手元のマシンにはCygwinを入れている。
だけど、.Netとかにはアクセスできないだろ? 今後のことも考えれば、PowerShellの方がいいと思うよ。
Re: (スコア:0)
NTFSはいいかげん (スコア:1)
「あ…ありのまま 今 起こった事を話すぜ!」的な (スコア:0)
>運の悪いことにテスト実行はスクリプトがおいてあるディレクトリ。いくつかスクリプトを仕上げていたんだが、これが全部なくなっていた…
こ、こわいなー。怪談にはまだ時期が早いですよ。
ホームディレクトリでこれやったら泣ける。
つーか、死ねる。
>コマンドプロンプトで空文字指定の del コマンドを実行してみる。
ひょっとして、Windows的には「空文字」と「引数無し」(或いはnull)の区別がないのか?
で、
del "" → del
に変換されて、デフォルト処理が「全削除」とか?
#「いや、その理屈はおかしい」。やっぱりMSの考えることは理解不能だ。
Re:「あ…ありのまま 今 起こった事を話すぜ!」的な (スコア:2)
そうであればまだ良かった。(del 単体だとエラーが出て実質「何もおこらない」)。
del "" -> del *
となってしまってるのが驚愕です。
ん? 俺、今何か言った?
Re:「あ…ありのまま 今 起こった事を話すぜ!」的な (スコア:1)
del .
と展開されたのだと思います
Re: (スコア:0)
大人の怪談 陞る~