コマンドプロンプトのcallと遅延展開

このQ&Aのポイント
  • コマンドプロンプトのcallと遅延展開について疑問があります。
  • バッチスクリプトでcallと遅延展開を使用すると、一部の出力がなくなる現象が発生します。
  • callはコマンドラインを2度解析するため、変数の展開が正常に行われないことがあります。
回答を見る
  • ベストアンサー

コマンドプロンプトのcallと遅延展開

こんにちは。 コマンドプロンプトにおいて、call と !・・・! による環境変数の遅延展開について、 1つ疑問に思う事がありましたので、質問させて頂きました。 まず、以下のようなバッチスクリプトtest.batを作成しました。 -------------------------------------------------------- @echo off setlocal setlocal enabledelayedexpansion set aaa=XXX^|cat echo 1:!aaa! call echo 2:!aaa! echo 3:%aaa% call echo 4:%aaa% --------------------------------------------------------- これを実行した結果、以下のようになりました。 --------------------------------------------------------- C:\Users\kei >test.bat 1:XXX|cat 3:XXX 4:XXX --------------------------------------------------------- callは、それ以降のコマンドラインを2度解析するだけなのに、 なぜ、call echo 2:!aaa! の行を実行した時に、何も出力されないのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.1

理由はよくわからないのですが、call 引数に""に囲まれない | とその後に何かあるとcall命令が実行されないようです。 call echo 2:!aaa! は、call実行の時点では、 call echo 2:XXX|cat となるので、callの第2引数は「2:XXX|cat」で、前述のようにこの行全体が無視されてしまいます。これは、遅延展開とか関係なく、下記でも確認できます。 SUBが表示されないだけでなく、FILE も出来ませんので表示が闇に消えているだけじゃ無くてcall先に飛んでないようです。 call :sub ^| more echo END goto :EOF :sub echo SUB echo TEST > FILE もちろん、| をエスケープせずに call :sub | more だとcallの結果をパイプしますが。 ところで、やりたいことは何ですかね?

関連するQ&A

  • バッチファイルの変数引継ぎについて

    行き詰ってしまったので、どなたか知恵を授けていただければと思います。 現在、あるソフトウェアの「バッチモード」という機能を使用したバッチを作成していて、構文が > sdcmd batch ***.txt 上記のようにコマンドを羅列したテキストファイルを指定した実行コマンドになります。 sdcmd以降はソフト指定のコマンド以外は使用できず、変数設定ができない為に変数設定とログ保存を兼ねて上記コマンドを記載したバッチを > setlocal EnableDelayedExpansion > set ○=△△△ > set ■=◇◇◇ > call aaa.bat %* >> aaa.log 2>&1 という内容の呼び出しバッチを作成たのですが、テキストファイル内の変数が代入されずに 実行されてしまいます。 cmd上から直接 > setlocal EnableDelayedExpansion > set ○=△△△ > set ■=◇◇◇ > sdcmd batch ***.txt >> aaa.log 2>&1 を実行しても変数の代入は行われませんでした。 cmd上で変数とテキストファイル内のコマンドを手動実行すれば変数は解決できます。 設定した変数を、テキストファイル内の変数値に代入する方法はあるでしょうか。

  • コマンドプロンプトのコマンド処理が途中で終了する

    メインbat内にサブ1bat、サブ2batが存在し以下構成になっています。 (サブ1batで作成したデータを用いてサブ2batの処理を行います。) 問題は メインbatを実行した場合、サブ1batが実行された後にサブ2batが実行されず終わってしまいます。 (メインbatにサブ1batだけ、メインbatにサブ2batだけだと、各々問題なく処理が行われることは確認。) 以下、メインbat処理----------------------------------- setlocal enabledelayedexpansion FOR /f "delims=, tokens=1-3" %%i in (テキストファイルパス) do ( IF "%%i"=="1" ( サブ1bat %%j %%k ) ) endlocal setlocal enabledelayedexpansion FOR /f "delims=, tokens=1-3" %%i in (テキストファイルパス) do ( IF "%%i"=="1" ( サブ2bat %%j %%k ) ) endlocal ---------------------------------------------------- ※テキストファイルパスはループのもとになっているcsvファイルです。 ※各サブbatは戻り値を返しません。 他の作業の合間に調べたりしているのですが一向に直せず困っています。 ご助力いただけると大変助かります。

  • コマンドプロンプトからのcmd実行について

    現在VBSでオブジェクトを定義しrunを使いcmd経由で他のバッチ・VBS・ソフトの起動をやっています。 ふととあるパスが実行できませんでした。 そこで別途個別にコマンドプロンプトだけで実行してみましたがやはりうまく処理できません。 [echo.bat] echo test pause [コマンドプロンプト] rem その1 cmd /K c:\temp\a\echo.bat rem その2 cmd /K C:\Temp\(a\echo.bat その1の結果 C:>cmd /K C:\Temp\a\echo.bat C:>echo test test C:>pause 続行するには何かキーを押してください . . . その2の結果 C:>cmd /K C:\Temp\(a\echo.bat 'C:\Temp\' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 C:> 上記のように1は正常に処理され2はうまく処理されません。 解決策をひたすら検索したのですが見つからず なんとなくだいたい分かったのが一部『(』や『)』や『&』や『@』や『^』などの記号が混じるとどうやらうまく処理できないようです。 なぜ処理できないのか?と、如何すればこれを回避して実行できるか分かる方がいればよろしくお願いします。 備考: (現状の緊急回避として記号のあるパスは記号のないパスから経由batを生成する方法を思いつきましたが自分で馬鹿だと思います) (経由バッチの中身が"C:\Temp\(a\echo.bat"ならば実行できるから) また、cmd /K "C:\Temp\(a\echo.bat" では実行できませんでした。 OSはXPです。コマンドプロンプトヴァージョンは(Microsoft Windows XP [Version 5.1.2600])です

  • コマンドライン引数の展開について

    バッチファイル内で%~dp0とすれば ファイルが保存されているディレクトリを取得できます。 これを利用して環境変数に set TEST=pushd %~dp0 とセットし、 %TEST% と展開することによって バッチファイルのディレクトリに移動しようとしたのですが、うまく行きませんでした。 ファイルが保存されている場所への移動手段をわかりやすくまとめたいです。 それ以外にも各バッチファイルの先頭で行う処理を共通化する目的があります。 以下のように第一引数として渡すやり方もあるのですが、 test.bat---- call common.bat %~dp0 common.bat---- pushd %~dp1 setlocal 共通化部分ではsetlocalを使うため、 別ファイルに分割してしまうと有効範囲が変更され都合が悪いのです。 何かうまい回避方法はありますでしょうか? (そもそも環境変数内で%~dp0が展開されてくれれば済む話なのですが…)

  • PowerShellからPowerShellを呼び出す方法

    PowerShellからPowerShellを呼び出す方法 次のバッチファイルと同等の事をPowerShellで行う方法を教えて下さい。 下記のような非常に簡易的なバッチファイルがあるとします。 ■ aaa.bat ■ echo test ■ aaa.bat ■ ■ bbb.bat ■ aaa.bat > aaa.log ■ bbb.bat ■ ■ コマンドプロンプト ■ cmd> aaa.bat ・・・ 下に「test」と出力される test cmd> bbb.bat ・・・ ファイルaaa.logに「test」と出力される ■ コマンドプロンプト ■ 同じ事をPowerShellでするとすれば ■ aaa.ps1 ■ echo "test" ■ aaa.ps1 ■ ■ PowerShellの画面から ■ PS > ./aaa.ps1 ・・・ 下に「test」と出力される test PS > ./bbb.ps1 ・・・ ファイルaaa.logに「test」と出力される ■ PowerShellの画面から ■ この時の「bbb.ps1」はどのようになりますか?

  • コマンドプロンプトにおけるコマンドライン引数の展開

    こんにちは。 コマンドプロンプトにおける、コマンドライン引数の展開のされ方について、質問させて下さい。 具体的に言うと、二重引用符で囲まれたコマンドライン引数が、 どのようにして各コマンドに渡されるのかを詳しく知りたいと思っています。 まずコマンドプロンプトが、コマンドラインの特殊文字を展開し、 それらが各コマンドに渡される事は知っています。 特に、2つの二重引用符で囲まれた文字列に含まれる特殊文字は普通の文字として扱われる事、 二重引用符は「\」によってエスケープできる事は知っています。 これらを理解した上で、以下のような事を試しました。 まず、以下のような、1.cというCプログラムを作成し、ビルドしました。 ____________________ #include <stdio.h> int main(int argc,char *argv[]) { int i; for(i=1; i<=9; i++) if(argv[i]) printf("argv[%d]=「%s」\n", i, argv[i]); return 0; } ____________________ 次に以下のようなバッチスクリプトを作成しました。 ____________________ @echo off echo %%~1:「%~1」 echo %%~2:「%~2」 echo %%~3:「%~3」 ____________________ その後、以下のようにして同じコマンドライン引数を、これらのプログラムに渡すと、 以下のような結果になりました。 ____________________ C:\Users\kei >1.exe "\"ab c\"" de argv[1]=「"ab c"」 argv[2]=「de」 C:\Users\kei >1.bat "\"ab c\"" de %~1:「\"ab」 %~2:「c\""」 %~3:「de」 ____________________ なぜ両者の出力結果に、違いが出るのかが分からず困っています。 コマンドプロンプロの仕様だと、1.exeの出力は予想通りだったのですが、 1.batの出力では、コマンドライン引数がスペースで区切られていると、 それらを二重引用符で囲んでも、1つの引数としてみなしてくれませんでした。 これだけでは不十分だと思い、以下のように、 Windowsコマンドではない、ダウンロードしてきたlessと Windowsコマンドであるtypeで、同じ事を試しました。 ____________________ C:\Users\kei >less "\"ab c\"" fa ab c: No such file or directory fa: No such file or directory C:\Users\kei >type "\"ab c\"" fa 指定されたファイルが見つかりません。 処理中にエラーが発生しました: \ab パラメータが間違っています。 ____________________ この結果をみると、lessでは1.exeと同じようにコマンドラインが解釈され、 moreでは1.batと同じようにコマンドラインが解釈されているようです。 こういった事実は 「まずコマンドプロンプトが、コマンドラインの特殊文字を展開し、 それらが各コマンドに渡される」 というコマンドプロンプトの仕様と矛盾しているので、頭が混乱しています。 こういった問題について、何か御存じの方がいらっしゃれば、情報提供をお願い致します。 長くなりましたが、よろしくお願い致します。

  • コマンドプロンプトのコマンド処理が途中で終わる2

    お世話になります。 以前 http://qa.itmedia.co.jp/qa9168537.html にて質問及び解決させていただいたのですが、 確認不足で思った処理にならない部分がありました。 上記URLの内容を抜粋します。 ============================================================= メインbat内にサブ1bat、サブ2batが存在し以下構成になっています。 (サブ1batで作成したデータを用いてサブ2batの処理を行います。) 問題は メインbatを実行した場合、サブ1batが実行された後にサブ2batが実行されず終わってしまいます。 (メインbatにサブ1batだけ、メインbatにサブ2batだけだと、各々問題なく処理が行われることは確認。) 以下、メインbat処理----------------------------------- setlocal enabledelayedexpansion FOR /f "delims=, tokens=1-3" %%i in (テキストファイルパス) do ( IF "%%i"=="1" ( サブ1bat %%j %%k ) ) endlocal setlocal enabledelayedexpansion FOR /f "delims=, tokens=1-3" %%i in (テキストファイルパス) do ( IF "%%i"=="1" ( サブ2bat %%j %%k ) ) endlocal ---------------------------------------- ※テキストファイルパスはループのもとになっているcsvファイルです。 ※各サブbatは戻り値を返しません。 ============================================================= この処理について サブ1bat及びサブ2batそれぞれの呼び出しで callを先頭に記述する必要があると以前回答いただき 処理としてはサブ1サブ2が全て処理されました。 そこで今回再動作検証した時にFORでループする件数が5件あったのですが、 5件だとサブ1batだけ5件処理が行われ、サブ2batの処理は行われないままメインbatが終了してしまいました。 FORでループする件数が1件だと問題ないなくサブ1サブ2それぞれ実行されたのですが、 複数件あると実行されませんでした。 どこに問題があるのかわからないので困っています。 宜しくお願いいたします。。

  • コマンドプロンプトのFOR文がダブルクリックで実行できない

    お世話になります。 まず当方の環境は以下になります。 OS:Windows XP Pro SP2 C:\tempにtest.batというバッチファイルを作成し以下を記述しました。 FOR /F "usebackq delims==" %%i IN (`set`) DO @echo %%i で、このtest.batをダブルクリックすると実行できないんです。 ただしコマンドプロンプトからでは問題なく実行できます。 また別PCではダブルクリック&コマンドプロンプトで問題なく実行できます。 どのようにすれば解決できるのかわからずに困っております。 どなたかアドバイスお願いできますでしょうか。

  • コマンドプロンプト(batファイル)のFORコマンド

    set aaa1=あああ set aaa2=いいい set aaa3=あいう set aaa4=かきく mkdir %aaa1% mkdir %aaa2% mkdir %aaa3% mkdir %aaa4% 上記のbatファイルをforコマンド(繰り返し処理)を使用してやってみたいです。 下記のbatファイルをつくってみたのですが、うまくいきません。 set aaa1=あああ set aaa2=いいい set aaa3=あいう set aaa4=かきく for /L %%B in (1,1,4) do mkdir %aaa%%B% pause %aaa%%B%のところが %aaa1%=>あああ や %aaa2%=>いいい になると思ったのですが... 文字列とforコマンドでの変数を組み合わせて、 DO処理側の変数として使うことはできないのでしょうか? 変な質問かとは思いますが、ご教授お願い致します。

  • コマンドプロンプトのFOR文がダブルクリックで実行できない。

    コマンドプロンプトのFOR文がダブルクリックで実行できない。 お世話になります。 まず当方の環境は以下になります。 OS:Windows XP Pro SP2 C:\tempにtest.batというバッチファイルを作成し以下を記述しました。 FOR /F "usebackq delims==" %%i IN (`set`) DO @echo %%i で、このtest.batをダブルクリックすると実行できないんです。 ただしコマンドプロンプトからでは問題なく実行できます。 また別PCではダブルクリック&コマンドプロンプトで問題なく実行できます。 どのようにすれば解決できるのかわからずに困っております。 どなたかアドバイスお願いできますでしょうか。

専門家に質問してみよう