私はこのような単純なバッチファイルを持っています:
エコーオフ taskkill / im "test.exe" / f> nul 一時停止
「test.exe」が実行されていない場合、次のメッセージが表示されます。
エラー:プロセス「test.exe」が見つかりません。
出力をNULにリダイレクトしたにもかかわらず、このエラーメッセージが表示されるのはなぜですか?
どうすればその出力を抑制できますか?
私はこのような単純なバッチファイルを持っています:
エコーオフ taskkill / im "test.exe" / f> nul 一時停止
「test.exe」が実行されていない場合、次のメッセージが表示されます。
エラー:プロセス「test.exe」が見つかりません。
出力をNULにリダイレクトしたにもかかわらず、このエラーメッセージが表示されるのはなぜですか?
どうすればその出力を抑制できますか?
回答:
エラーメッセージはしばしば行きstderr
ませんのでstdout
です。
呼び出しをこれに変更します。
taskkill /im "test.exe" /f >nul 2>&1
そして、すべてが良くなります。
これstdout
は、ファイル記述子1でありstderr
、慣例によりファイル記述子2であるため機能します。(stdin
ちなみに0はです。)2>&1
コピーは、nullデバイスにリダイレクトされたばかりの新しい値1から出力ファイル記述子2をコピーします。
この構文は(大まかに)多くのUnixシェルから借用されていますが、シェル構文とCMD.EXEの間には微妙な違いがあるため、注意する必要があります。
更新: OP NUL
がここに書き込む名前の「ファイル」の特殊な性質を理解していることはわかっていますが、コメンターは理解していなかったため、その側面についてもう少し詳しく説明します。
MSDOSの最初のリリースまでさかのぼると、特定のファイル名はファイルシステムカーネルによって横取りされ、デバイスの参照に使用されていました。それらの名前の最も初期のリストが含まれNUL
、PRN
、CON
、AUX
とCOM1
てCOM4
。NUL
nullデバイスです。読み取りまたは書き込み用に常に開くことができ、任意の量を書き込むことができ、読み取りは常に成功しますが、データは返しません。その他には、パラレルプリンターポート、コンソール、および最大4つのシリアルポートが含まれます。MSDOS 5の時点で、さらにいくつかの予約名がありましたが、基本的な規則は非常によく確立されていました。
Windowsが作成されたとき、それはMSDOSカーネルの上にあるかなり薄いアプリケーションスイッチングレイヤーとして始まったため、同じファイル名の制限がありました。Windows NTがそれ自体で真のオペレーティングシステムとして作成されたとき、NUL
およびのような名前は、COM1
それらを排除できるほど機能するとは考えられていませんでした。ただし、新しいデバイスが常に実際のファイルのそれらの名前の将来のユーザーをブロックする名前を取得するという考えは、明らかに不合理です。
Windows NTとそれに続くすべてのバージョン(2K、XP、7、および現在8)はすべて、カーネルコードから、さらに注意深く構築された、移植性の低いユーザー空間コードに、より複雑なNT名前空間を使用します。その名前空間では、デバイスドライバーは\Device
フォルダーを通じて表示されます。必要な下位互換性をサポートするため\DosDevices
に、ファイルシステムフォルダー内の予約済みファイル名のリストを実装するフォルダーを使用する特別なメカニズムがあります。ユーザーコードは、通常のWin32 APIの下のAPIレイヤーを使用して、この内部名前空間を参照できます。カーネルの名前空間を探索するための良いツールがあるWinObj MicrosoftのSysInternalsのグループから。
Windowsでのファイル(およびデバイス)の正当な名前を取り巻く規則の完全な説明については、MSDNのこのページは有益であり、困難なものになります。ルールは多くのより多くの彼らがあるべきよりも複雑で、そして「どのくらいの時間、最長法的完全修飾パス名は?」など、いくつかの簡単な質問に答えるために、実際には不可能です。
taskkill /im "test.exe" /f >%temp%\nul 2>&1 & del %temp%\nul
。これにより、空のnullファイルがローカルディレクトリに配置されなくなります
NUL
は予約されたファイル名で、NULデバイスにマップされます。NUL
どのディレクトリでもという名前の実際のファイルを作成することはできません。
代わりにこのスクリプトを使用してください:
@taskkill/f /im test.exe >nul 2>&1
@pause
この2>&1
部分が実際に行うことは、stderr
出力をにリダイレクトすることstdout
です。以下で詳しく説明します。
タスク「test.exe」を終了します。にリダイレクトstderr
しstdout
ます。次に、にリダイレクトstdout
しnul
ます。
Press any key to continue . . .
誰かがキーを押すまで、一時停止メッセージを表示します。
注:@
記号は、各コマンドのプロンプトを非表示にしています。この方法で最大8バイトを保存できます。
スクリプトの最短バージョンは次のようになります
@taskkill/f /im test.exe >nul 2>&1&pause
。&
文字は最初にリダイレクトに使用され、2回目にコマンドを分離するために使用されます。文字が並んで二度必要とされていません。あなたが投稿したものは49バイトですが、このコードは40バイトです!実際に9バイト節約しました。よりクリーンなコードについては、上記を参照してください。@
代わりにこれを行うこともできます:
tasklist | find /I "test.exe" > nul && taskkill /f /im test.exe > nul
> nul
と>$null
。