- ベストアンサー
バッチ内で、echoがonかoffか判定する方法
上記がなかなかうまく行きません。 いい方法は無いでしょうか? 条件: 純粋にバッチコマンドだけで判定する。
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
回答10についてですが、bunjiiさんのところではそれでうまくいくんですか? 私のところでは、パイプを使用すると、常にデフォルトの設定(ON)の動作になります。 なので、回答4を記載したわけですが。 念のため、Windows10のマシンでも試しましたが、同様の結果でした。
その他の回答 (10)
- bunjii
- ベストアンサー率43% (3589/8249)
質問の文言を読み返し、他の解答者への補足も参考に用途は無視してバッチコマンド(Windows OSのコマンド)のみで現在のecho on/off状態を検知してon/offの切り替え方法するには次のようにすれば可能と思います。 echo onのときにecho offを実行し、echo offのときは何もしない。 echo | find "OFF" if %errorlevel%==1 echo off echo offのときにecho onを実行し、echo onのときは何もしない。 echo | find "ON" if %errorlevel%==1 echo on 但し、親のバッチから呼び出されて、親のバッチへ戻ったときは親のバッチへecho on/offの状態は引き継がれません。 つまり、子プロセスで変更したecho on/offの結果は親に戻るとき破棄されて、親プロセスが子プロセスを呼び出したときの状態に戻ります。 echoコマンドの結果をfindコマンドの比較対象にするためパイプ(|)を使用しています。これについては既にテスト済みと思います。 findコマンドで検索文字列が無いとき、環境変数のerrorlevelは1となり、検索文字列があるときはerrorlevelが0になります。 今回の回答はコマンドの動作状況を確認し、バッチプロセスの親子関係でどのような動作になるかを検証した結果です。 尚、当方の環境はWindows 7および10のバッチファイルの動作で確認しました。
補足
No.11さんがコメントされていますが、 当方でも散々試し、 原因を推定し、うまく行かないのを何とかうまく行かせる回避策も 散々試しましたが、 どうしてもうまい方法が見つかりませんでした。 そこでokwavに相談させて頂くことにしました。 そちらでは成功したのかしていないのかは分かりませんが、 同じことを当方でやっても失敗しています。 原因の推定や対策のアドバイスがあればそれをお願いします。
- notnot
- ベストアンサー率47% (4900/10359)
No7の回答は、あくまで、 >得てしてそういう問題は、 >既に議論されてうまい方法が見つかっていたりしますから。 に対しての物です。「一時ファイルを作らずに現在のエコー状態を知る」というのを切実に議論した人が多いとは思えません。一時ファイルを作成するというのはOSや標準プログラムがいくらでもやっているごく普通のことなので、クイズ問題でも無ければ、普通の人はそういう制限を持ちません。ということで、私はこの質問をクイズ的に捉えていますので、「一時ファイルを作れ」と薦めているわけじゃ無いです。誤解無きよう。 ところで、「一時的にエコーしない」は解決済みで良いですよね? 「一時的にエコーする」は、No5の回答の時に ・自分でechoする ・サブプロセスのバッチファイルで処理する という2案を出していますが、それは何故駄目なのでしょうか? 「自分でechoする」は私もたまにやります。
補足
もともとダメもとで聞いただけですけどね。 okwavでは切実と多くの人間が感じるものだけが 対象にされているとも思っていませんし。 もしあれば幸いということでした。 最初からプログラムするのでもなく、 かつて自分で作り自分で使っているものに手を入れるのでもなく、 既にある、仕様書も無いものにある処理を挿入するような場合を 想定しています。 もちろん契機はありましたよ、ある種の特定の作業をしていて、 そういう場面に遭遇し、掲題のうまい方法は無いか?と考え始めました。 しかし当初簡単だと思いましたがそうではないと気付き、 その作業は全体を慎重に精査し片を付けました。 しかし本当にそういう方法は無いのか? は、暇な時に時々思い出して考え続けていたということです。 何の副作用も起こさない、統一的な方法やスタイルは無いだろうか? もしあればそれを認識しノウハウとして蓄積しておきたい、 ということです。 特定の問題に対し、対処法が分からず困って相談している、 ということではないのです。 当方の説明も十分ではないのかもしれませが、 この趣旨が理解いただけない方が多いなあとつくづく感じました。
- bunjii
- ベストアンサー率43% (3589/8249)
補足として投稿がありましたので続投させて頂きます。 >求めているのは、 >極力本体を解読せずに、 >他の部分に影響しない、他の部分から影響されない、 >それを最小限の作業量、複雑さで全くない、 >「機械的な処置」により実現するうまい方法はないか?です。 あなたの意図が読めなくなりました。 echo onまたはoffの状態を検知してoffのときはonにするバッチファイルをサブモジュールとして作成したいのでしょうか?、またはサブモジュールのバッチファイルの中でecho offのときonにしたいのですか? 私はメインのバッチファイルの中でサブモジュールを呼び出す前にサブモジュールがecho onの環境を要求するときメインのバッチファイルでecho offのときonに切り替えてからサブモジュールを呼び出すものとする解釈していました。 何れにしてもバッチファイルの実行では多機能を求めるようなものではないようですから込み入った処理を考えない方が良いと思います。 バッチファイルの実行ではメインの環境のecho on/offは呼び出されたサブのバッチファイルへ引き継がれます。しかし、サブのバッチファイルでecho on/offの操作を行ってもサブのバッチファイルが完了して制御がメインのバッチファイルに戻るとサブを呼び出した時点のecho on/offの状態に戻るようです。 従って、汎用のバッチファイルとしてecho on/offの状態をチェックしてサブのバッチファイルとして呼び出すことは無意味のように思います。 尚、他の回答者から出ている状態を一時ファイルに書き出して切り替え後に一時ファイルを削除する案はダメなのですか?(期待する結果にならないと思いますが考え方もダメですか?) あなたと私の考え方の相違で私の考え方が受け入れられないのであれば補足もお礼も要りません。
補足
回答していただいて申し訳ありませんが、 意図が読めないならこれ以上は結構です。 ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10359)
No5です。 >得てしてそういう問題は、 >既に議論されてうまい方法が見つかっていたりしますから。 普通は一時ファイルを作って、何の問題も無く解決しているんでしょう。 一時ファイルを作れないというきわめて特殊な事情でだけ無理なんだと思いますよ。
補足
一時ファイルを作っていいというなら最初から質問していません。 もしそれしかないと確信されているのなら、回答は、 「方法はありません」 でいいと思います。 私も方法はなさそうだと感じ始めていました。 一度ファイルを作りたくないと条件提示したのですから、 それをごり押ししても回答にはなり得ません。 趣味で作ったりとか新規に何かを作る場合なら、 それが仕様ということでいいかもしれないし、 そもそも最初から、on/offがどうなっているかわからないようなものは作りません。 しかし既存の何かに手を入れる、 どう運用しているかも分かっていない、 そう条件下でファイルを作るということは、 そこにはどういうファイルが置かれるか分からず、 今は無くても将来バッティングするかもしれません。 それを避けて一時ファイルを定常的に残置するなら、 それは常に本体とペアで扱わなければいけないファイルとなります。 これは新たな制約条件の発生です。 残置しない場合でも、使う側にそのファイル名のファイルを置くなと言えば、 それも紛れもなく新たな制約を発生させたということになります。 着目したプログラムだけが動けばいいというなら簡単ということです。 「他に影響を与えない」 これが大事なんです。 私はこれを特殊な事情とは思いません。
- bunjii
- ベストアンサー率43% (3589/8249)
>プログラム実行時にechoのon/offを検出し、状態に応じて処理を変えたいということです。 バッチの中で検出するのはナンセンスではないでしょうか? 検出する段階で強制的にecho on/offを適宜実行すれば良いだけです。 既にある特別処理用コマンドを実行する前にecho onが望ましければecho onをバッチファイルへ追加すれば良いし、次の別コマンドを実行するときecho offにすべきであれば直前にecho offにすれば解決しませんか? >具体的には、コードが実行され、差し込まれた部分に至った段階で、 そのコードとは別のプログラム言語でコーディングした汎用モジュールと言うことですよね? そのモジュールをバッチファイルから呼び出して実行すると言う考え方ですよね? >実際には条件分岐の先で異なるon/off状態を経てそこに至り、実行時にしか状態が決まらないという場合も想定されます。 特定のモジュールを実行する前にそのモジュールを実行する環境としてecho onまたはoffの何れかが適当と言うことはあなたが判断できるのですよね? 特定モジュールの実行途中でecho on/offの切り替えが必要と言うことでれば、その特定モジュールのコードを修正しなければなりません。 特定モジュールの実行環境をバッチで調整するのであれば強制的にecho on/offを切り替えれば良いことのように思います。(チェック不要)
補足
影響する部分を完全に解読して対処する方法をお聞きしているのではありません。 求めているのは、 極力本体を解読せずに、 他の部分に影響しない、他の部分から影響されない、 それを最小限の作業量、複雑さで全くない、 「機械的な処置」により実現するうまい方法はないか?です。 これは、#3の補足の繰り返しです。 もしご回答頂けるなら、 元の質問を別の質問に変えるのではなく、 元の質問にそくしたご回答をお願いします。
- notnot
- ベストアンサー率47% (4900/10359)
一見、 for /f "tokens=2 delims=<>" %%A in ('echo') do set ECHO=%%A で状態がとれそうに思いますが、'echo'のコマンドは、今実行しいているcmd.exeじゃなくて新たに子プロセスとして生成されたcmd.exeで実行されるので、常に初期状態のecho onの状態です。 (余談ですが、仮にこれで取れたとしたら、findとか使う必要なくて、if %ECHO% == OFF でいいです。) >具体的には、コードが実行され、差し込まれた部分に至った段階で、 >offだった場合は、一旦onにして処理が終わったらoffに戻す、 >onだった場合は、on/offについては何もせず処理する、 >あるいはそれらの逆、 全体のECHOの状態に関係なく、ここの部分だけ一時的にECHO ONの状態にしたいとか、ECHO OFFの状態にしたいと言うことですよね? ファイルを作って判定するのが駄目なら、自分でechoするしかないでしょう。 @echo %CD%^>date /t @date /t と書けば、echoの状態に関係なく、 C:\Temp>date 2017/05/20 が表示されます。括弧とか使っていると面倒ですが、出来ない話では無い。 逆の場合だと、単に@をつければいいかと。 あるいは、その部分が独立できる処理なら、別のBATファイルにしておいて、 cmd /c その部分処理.BAT で、そのBATファイル内で独自にECHO状態が設定できます。
補足
ご回答ありがとうございました。 >cmd.exeじゃなくて新たに子プロセスとして生成されたcmd.exeで実行されるので、常に初期状態のecho onの状態です。 そうですね。二番目の方に補足で「別の世界」と表現したのはそれです。 全てのコマンドに@をつけるというのは、 on/offにかかわらず余分な表示がなくなります。 実際、この問題を考え始めた時の問題はそのケースでした。 しかし、そこで考え始めたのは、 逆の場合も想定し、いかなる場合も対応できる汎用な方法は無いか? でした。 つまり、元々offであってもそこだけonにしたい、 onにした後元の状態に戻しておきたい、そういう場合です。 どこかから持ってきて差し込むような場合など、 内部にon/offがあるかもしれません。 その種の場合も含めて一挙に解決するようなうまい方法は無いか? と思って探し始めました。 そうしたら意外なことにちっともみつからなくて okwavで聞いてみようと思ったのです。 得てしてそういう問題は、 既に議論されてうまい方法が見つかっていたりしますから。
- m-take0220
- ベストアンサー率61% (480/785)
> 私の取り出し方、echo %ECHOSTATE%とパイプのfindの組み合わえで ECHOSTATEが「ON」や「OFF」の場合、 echo %ECHOSTATE% は echo ON または echo OFF になるため、ECHOSTATEの内容を表示するのではなくECHOの状態を設定するコマンドと認識されてしまいます。 このような場合は echo.%ECHOSTATE% とするとうまくいきます。 が、私の環境(Windows8.1)では、常にデフォルトの設定が表示されてしまうようです。 findの内部でechoを実行したり、 echo | find "ON" とパイプを使用したりすると、直前にecho offを実行していても「ECHOは <ON> です。」になってしまいます。 ただし、 echo off echo > test.txt とすると、test.txtは「ECHOは <OFF> です。」になります。 リダイレクトとパイプで、動作内容がかわるのもよくわかりません。 ちなみに、 echo.%ECHOSTATE% | find "ON" のようにパイプを使用すると、テンポラリフォルダに一時ファイルを作成して、実行後削除しています。 これが許されるのであれば、 echo > %TEMP%\echostate.txt find "ON" < %TEMP%\echostate.txt <ERRORLEVELで判断> del %TEMP%\echostate.txt でもいいんじゃないかと思います。findじゃなくてforで「ON」や「OFF」を環境変数に取り出すことも可能です。
補足
そうですか、やはりファイル生成以外にありませんか。 ありがとうございました。 当方もこんなのなんとかなるだろ、と安易に思い、とりかかったのですが、 すぐできるつもりでいたのがなかなかうまく行かず、 ちょくちょく断続的に考え、トータル数時間は首をひねったと思います。 でもできませんでした。
- bunjii
- ベストアンサー率43% (3589/8249)
>いい方法は無いでしょうか? バッチファイルはテキストファイルと同じようにメモ帳で編集できます。 メモ帳で開いて目視で読むと分かるはずです。 echo off の行があればそれ以降がoffです。 echo off の後に echo on があればその行以降がonに切り替わっています。 一般的にデフォルトでは echo on になっていると思います。 バッチ開始前はデフォルトなので環境変数を確認すればわかるでしょう。 バッチ終了後はデフォルトに戻るはずです。
補足
コード全体を見ろ、ではさすがに回答になっていないでしょう。 何らかの理由でそれが分からないからプログラムでなんとか検出しよう、 ということではないのです。 プログラム実行時にechoのon/offを検出し、 状態に応じて処理を変えたいということです。 かなり狭い視野で持論を展開しておられるようですが、 当方は、 例えば、既に存在しているプログラムを改造して あるコードを差し込むような場合、 全体を見て、解読して、それで判断して差し込むコードを書く、 というような手間をかけることを避ける方法を模索しています。 全体を見ろでは残念ながら解決になりません。 具体的には、コードが実行され、差し込まれた部分に至った段階で、 offだった場合は、一旦onにして処理が終わったらoffに戻す、 onだった場合は、on/offについては何もせず処理する、 あるいはそれらの逆、というようなことをしたいのです。 また静的な場合しか考慮されていないようですが、 実際には条件分岐の先で異なるon/off状態を経てそこに至り、 実行時にしか状態が決まらないという場合も想定されます。 これを、 「そんなコードを書くヤツが悪い」、と言えてしまうなら問題はありません。 しかし現実にはそうは行かないのです。 ・手早く、 ・問題を起こすことなく、 ・差し込んだ場所以外に影響を与えることなく、 ・全体を解読することなく、 作業する方法を探しているということです。
- m-take0220
- ベストアンサー率61% (480/785)
for /f "tokens=2 delims=<>" %%i in ('echo') do @set ECHOSTATE=%%i とすると、環境変数ECHOSTATEが「ON」または「OFF」に設定されます。
補足
ご回答ありがとうございます。 ところでそれは既に試行しました。 一見うまく行くよに見えますが、 ECHOSTATEから値を取り出す時にうまく行きません。 おそらく ・(`echo`)が実行しているバッチと別の世界で実行されているか、 私の取り出し方、echo %ECHOSTATE%とパイプのfindの組み合わえで なにがしかの要因でうまく行かないのだと思います。 ちなみに<ON>や<OFF>の<や>が悪さをしている可能性も考え、 set ECHOSTATE=%ECHOSTATE:<=% set ECHOSTATE=%ECHOSTATE:>=% とした後、 echo %ECHOSTATE% | find "ON" や echo %ECHOSTATE% | find "OFF" としてerrorlevelで判定しようとしても失敗します。 できれば判定がうまく行く部分まで含めて例を示して戴きたいのですが。
- kawais070
- ベストアンサー率52% (2242/4283)
echo > tempfile.txt とすると、tempfile.txt に、 ECHO は <ON> です。 または、 ECHO は <OFF> です。 のどちらかが入りますね。 前者はファイルサイズが21で後者は22です。 あとは、tempfile.txtのファイルサイズで判定できます。 http://buty4649.hatenablog.com/entry/2013/09/10/%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%B0%8F%E6%8A%80 上記のページに、バッチでのファイルサイズ取得方法が書かれています。
補足
ご回答ありがとうございます。 言い忘れましたが、ファイルも生成したくありません。 ファイルを生成しない方法は無いでしょうか?
お礼
ということで、補足で説明した通り、目的はほぼ達せられました。 コメントを頂いた全員の方にベストアンサーを差し上げたいのですが、 制度上そうも行きません。 代表して差し上げることにします。 ありがとうございました。
補足
そうですね、 当方も 「こんなもの」 と安易に考え、簡単にやれるだろう、そう思って考え始めました。 相談した趣旨は、 いい方法はたぶんないのではないか? しかしこういうものは得てして 虚を突くような定番の方法が周知されていないとも限らない。 もしそういうものがあれば知りたいし、 そういうものが無くても、 そういうものがなさそうだという感触がつかめればいい、 ということでした。 そういう意味では、 多くの詳しい方の投稿を拝見して、 その感触はほぼつかめたと思いますので 目的はほぼ達せられたという感じですね。