Warum nicht @ECHO ON/OFF arbeiten innerhalb einer batch-Datei IF-block?

@echo on und @echo off scheinen nicht zu haben einen Einfluss bei der Ausführung innerhalb einer in Klammern if block in einer batch-Datei. Hier ist eine einfache demo:

@echo off
echo Test #1
if 1 == 1 (
  @echo on
  echo Test #2
  @echo off
  echo Test #3
)
@echo on
echo Test #4

Die Ausgabe durch die Ausführung des oben in der Befehlszeile:

Test #1

Test #2

Test #3

C:\mybatchfilelocation>echo Test #4

Test #4

Könnte jemand das erklären und/oder schlagen eine Lösung? (Erwarten, dass es könnte möglicherweise behoben werden, durch reichliche Verwendung von goto und Etiketten, würde aber lieber weiterhin mit Klammern, wenn die Blöcke wenn möglich…)

  • Ich denke, es ist, weil der aktuelle echo on/off Zustand wirkt sich auf die gesamte Zeile oder block nur, wenn Sie kontrollieren möchten, es wird für jeden Befehl einzeln, legen Sie dann echo on und vor jedem Befehl, den Sie verstecken wollen, mit @;
  • Danke, aber leider sieht es so aus echo on wird nicht von echo-Befehle innerhalb der Klammern (siehe meine neu hinzugefügte Antwort unten).
  • Ich verstehe nicht, beide echos in deiner Antwort sind echoed; setzen @ vor einem der echos zu verbergen; fügen Sie @ vor der ( zu verbergen alles, was nach if
  • Dies ist nicht praktikabel – ich will nicht die if Anweisung selbst auch: Wenn ich @if keiner wird es zurückgegeben werden, sondern mit jeder anderen Nutzung der @ ich gehe immer zu sehen, die if 1 == 1 Befehl als echo zumindest.
  • Ah, jetzt sehe ich… ja, das @ blendet die echo des ganzen (folgenden) Befehl-Linie; leider gibt es keine echo on-Zeichen, so müssen Sie die Arbeit mit gotos und labels, obwohl der code sieht schrecklich…



4 Replies
  1. 6

    Als Sie entdeckt haben, die geändert ECHO Staat wird nicht erkannt durch den parser, bis es erreicht eine Anweisung, die nach dem code-block mit ECHO ON/OFF.

    Aber es gibt eine Ausnahme – die Befehle nach der FOR … DO nehmen auf den Zustand ändern, in dem gleichen block 🙂

    Beachten Sie, dass Sie brauchen nur @ zu unterdrücken Befehl ausgegeben, wenn ECHO ist derzeit AUF. Wenn es DEAKTIVIERT ist, dann gibt es keine Notwendigkeit für @ECHO ON. Und wenn Sie Sie ein-und AUSSCHALTEN innerhalb der gleichen code-block, dann brauchst du es nicht es entweder.

    Hier ist eine demo, die echos der test-Linien:

    @echo off
    echo Test #1
    (
      echo on
      for %%. in (.) do echo Test #2
      echo off
      echo Test #3
      echo on
      for %%. in (.) do echo Test #4
      echo off
      echo Test #5
    )
    echo on
    echo Test #6
    @echo off
    echo Test #7
    

    — OUTPUT —

    Test #1
    
    C:\test>echo Test #2
    Test #2
    Test #3
    
    C:\test>echo Test #4
    Test #4
    Test #5
    
    C:\test>echo Test #6
    Test #6
    Test #7
    

    Vielleicht finden Sie es bequem, zu erklären, eine einfache echo_on „makro“. Die folgende produziert, die genau die gleiche Ausgabe:

    @echo off
    setlocal
    
    set "echo_on=echo on&for %%. in (.) do"
    
    echo Test #1
    (
      %echo_on% echo Test #2
      echo off
      echo Test #3
      %echo_on% echo Test #4
      echo off
      echo Test #5
    )
    echo on
    echo Test #6
    @echo off
    echo Test #7
    
    • Super Antwort, und netter trick! Nur eine Sache, weißt du etwas über die Interna – also warum FORDO ist die Ausnahme von der Regel?
    • Ich nehme an, weil FÜR die ist der einzige Befehl, der ECHOs mehrfach. Der erste ECHO für die gesamte FOR-Anweisung unterdrückt wird. Aber das TUN die Befehle werden anschließend Hallte einmal für jede iteration. Siehe stackoverflow.com/a/4095133/1012053 für mehr info.
  2. 2

    Habe gerade herausgefunden, was die Ursache für diese, indem Sie das echo auf vor eine if block.

    @echo on
    if 1 == 1 (
      echo Test #1
      echo Test #2
    )
    

    Dieser Ausgänge:

    C:\mybatchfilelocation>wenn 1 == 1 (

    echo Test #1

    echo Test #2

    )

    Test #1

    Test #2

    Also die Aussage, dass das echo ist die gesamte if-block anstatt jede Anweisung innerhalb es. Diese Antwort erklärt sich dadurch weiter und diese Antwort gibt einen workaround – leider nicht das, was ich hören wollte, aber es sieht aus wie viele gotos und labels, die vielleicht die einzige praktikable Lösung.

    • In meiner Erfahrung, die Schaffung eines „Blocks“ mit den Klammern ist wirklich nicht wie so etwas in einer echten Programmiersprache, weil die ganze Sache wird analysiert/var-substituierte auf einmal, bevor es überhaupt laufen. Ohne jemals ausprobiert, was du tust, würde ich es erwartet habe, zu arbeiten, wie Sie getan haben, aber ich kann nicht sagen, dass ich überrascht bin zu sehen, schrulligen Verhalten von cmd/wenn.
    • Dieses Verhalten ist die gleiche, die erforderlich verzögerte Erweiterung zugreifen geänderten Variablen innerhalb eines Blocks: wenn echo on bevor der block, der alle Zeilen im block werden gezeigt, auch, wenn man einen echo off im inneren, und Umgekehrt: wenn echo off vor den block, alle Linien werden nicht angezeigt, auch mit einem echo on im block. Die Letzte echo-status wird in der ersten Zeile nach dem block.
  3. 2

    Konnten Sie so etwas tun, um zu erreichen das Ergebnis das Sie wollen:

    @echo off
    set "ExecuteCmd=echo Test #2"
    echo Test #1
    if 1 == 1 (
      echo %ExecuteCmd%
      %ExecuteCmd%
      echo Test #3
    )
    @echo on
    echo Test #4
    
    • Kein schlechter Versuch, eine alternative aber da gibt es viele mögliche Befehle, die ausgeführt werden können innerhalb eines if block sieht es aus wie gotos und labels sind eher die praktische.
  4. 1

    Wie über das setzen der echo-Steuer-Befehle im Unterprogramm?

    @echo off
    echo Test #1
    if 1 == 1 (
      CALL :DO_ECHO_ON
      echo Test #3
    )
    @echo on
    echo Test #4
    
    @EXIT /B
    
    :DO_ECHO_ON
    @ECHO ON
    echo Test #2
    @ECHO OFF
    @EXIT /B
    

    Diese produziert die Ausgabe, die ich erwarten würde von deiner Beschreibung.

    Test #1
    
    C:\secret>echo Test #2 
    Test #2
    Test #3
    
    C:\secret>echo Test #4 
    Test #4
    

    Basierend auf Ihre Kommentare, ich nehme an, Sie wollen in der Lage sein wiederum echo auf die beliebigen Befehle. Diese modifizierte version macht das.

    @echo off
    echo Test #1
    if 1 == 1 (
      CALL :DO_ECHO_ON_CMD echo Test #2
      echo Test #3
      CALL :DO_ECHO_ON_CMD dir /b "C:\Program Files"
      echo Test #3.1
      CALL :DO_ECHO_ON_CMD attrib c:\Windows
    )
    @echo on
    echo Test #4
    
    EXIT /B
    
    :DO_ECHO_ON_CMD
    @ECHO ON
    %*
    @ECHO OFF
    @EXIT /B 0
    

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.