素晴らしい興味深い質問(+1)
このスペースは、SORTではなく、CMDパーサーのパイプメカニズムによって導入されます。
FOR / Fを使用してコマンドを実行すると、コマンドは独自のCMDシェルで実行されます。また、パイプの各側は、独自のCMDシェルで実行されます。パイプされたコードブロック内で遅延拡張が失敗するのはなぜですか?を参照してください。詳細については。
したがって、コマンドは実際に3つのCMDシェルをインスタンス化します。1つはFOR / Fコマンド用であり、パイプの各側に2つ作成されます。
%CMDCMDLINE%動的変数を使用して、コマンドがどのように解析され、CMDシェルに送られるかを確認できます。コマンドラインからコマンドを実行しているため、変数名の少なくとも1つの文字を2回エスケープして、最も内側のCMDシェルに到達するまで展開されないようにする必要があります。
結果を含むコマンドは次のとおりです(先頭>
は私のコマンドプロンプトです):
>for /f "delims=" %a in ('(echo %^^^cmdcmdline%^&for /l %z in (1,1,10^) do @echo %z^)^|sort') do @echo %a0
1 0
10 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
C:\Windows\system32\cmd.exe /S /D /c" ( echo %cmdcmdline% & FOR /L %z in (1 1 10) do @ echo %z )" 0
出力の最後の行は、パイプの左側に使用されるコマンドラインです。パーサーが多くの場所にスペースを追加した方法を確認できます。
ECHOコマンドの代わりに、単純なバッチスクリプトを使用して値をエコーすることにより、問題を回避できます。
echoArgs.bat
@echo(%*
このコマンドを実行すると、目的の結果が得られます。
>for /f "delims=" %a in ('(for /l %z in (1,1,10^) do @echoArgs %z^)^|sort') do @echo %a0
10
100
20
30
40
50
60
70
80
90
この問題を回避するもう1つの方法は、ECHOコマンドを使用して変数を作成し、変数の展開を適切にエスケープすることです。
>set cmd=@(echo %z)
>for /f "delims=" %a in ('(for /l %z in (1,1,10^) do %^^^cmd%^)^|sort') do @echo %a0
10
100
20
30
40
50
60
70
80
90
編集
>_tempfile echo and here's a space|more
例も面白いです。出力ファイルの最後に余分なスペースがあります。しかし、Chad Nouisは、左側のリダイレクトのために何もソートされていないというのは正しいです。右側で任意のコマンドを使用でき、結果は同じになります。
問題の原因は依然としてパーサーですが、パーサーがコマンドを再構築する方法は興味深いものです。
>>_tempfile echo %^cmdcmdline%|rem
>type _tempfile
C:\Windows\system32\cmd.exe /S /D /c" echo %cmdcmdline% 1>_tempfile"
コマンドの最初から最後にリダイレクトがどのように移動され、のファイルハンドル1
が明示的に追加されているかに注目してください。あなたは確かに余分なスペースがどこから来ているかを見ることができます。