2011-02-13 16 views
78

In un file batch DOS possiamo avere solo una riga se il corpo dell'istruzione? Penso di aver trovato da qualche parte che potrei usare () per un blocco if come lo {} utilizzato nei linguaggi di programmazione C-like, ma non sta eseguendo le istruzioni quando provo questo. Nessun messaggio di errore neanche. Questo il mio codice:Posso avere un blocco IF nel file batch DOS?

if %GPMANAGER_FOUND%==true(echo GP Manager is up 
goto Continue7 
) 
echo GP Manager is down 
:Continue7 

Stranamente né "GP Manager è up" o "GP Manager è down" viene stampato quando ho eseguito il file batch.

+0

Forse questo potrebbe aiutare: http://commandwindows.com/batchfiles-branching.htm – esaj

+0

Ya, questo aiuta. DOS fa schifo. Se voglio usare più istruzioni in se altrimenti devo usare && tra le istruzioni? o c'è un modo più elegante? –

risposta

108

Si può effettivamente creare un blocco di istruzioni da eseguire dopo un condizionale. Ma hai la sintassi sbagliata. Le parentesi devono essere utilizzati esattamente come mostrato:

if <statement> (
    do something 
) else (
    do something else 
) 

Tuttavia, non credo che non v'è alcun built-in sintassi per else-if dichiarazioni. Sfortunatamente sarà necessario creare blocchi nidificati di istruzioni if per gestirli.


In secondo luogo, il test %GPMANAGER_FOUND% == true sembra molto sospettoso per me. Non so a cosa sia impostata la variabile d'ambiente o come la stai settando, ma dubito fortemente che il codice che hai mostrato produrrà il risultato che stai cercando.


Il seguente codice di esempio funziona bene per me:

@echo off 

if ERRORLEVEL == 0 (
    echo GP Manager is up 
    goto Continue7 
) 
echo GP Manager is down 
:Continue7 

Si prega di notare alcuni dettagli specifici circa il mio codice di esempio:

  • Lo spazio aggiunto tra la fine dell'istruzione condizionale, e la parentesi di apertura.
  • Sto impostando @echo off per non visualizzare tutte le delle istruzioni stampate sulla console mentre vengono eseguite, e invece è sufficiente vedere l'output di quelli che iniziano specificamente con echo.
  • Sto usando la variabile integrata ERRORLEVEL solo come test. Per saperne di più here
+0

Migliore utilizzo se% ERRORLEVEL% == 0, poiché l'altra variante è sempre true, perché IF ERRORLEVEL è true, se errorlevel è uguale o superiore a , il "==" viene ignorato in questo caso – jeb

+0

@jeb: Penso potresti aver perso il punto. Usare 'ERRORLEVEL' non è la risposta al suo problema. Stavo semplicemente postando un esempio della sintassi corretta. * In entrambi i casi la forma * è accettabile, proprio come sarebbe 'if 0 == 0' o qualsiasi altra espressione banale. Ma in effetti, assicurati di comprendere la differenza tra la variabile di ambiente '% ERRORLEVEL%' e il 'ERRORLEVEL' interno del processore dei comandi. Raymond Chen lo spiega bene [qui su questo blog] (http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx). –

+0

Puoi avere un ELSE SE? – xagyg

12

Logicamente, la risposta dovrebbe lavoro di Cody. Tuttavia non penso che il prompt dei comandi gestisca logicamente un blocco di codice. Per la vita di me non riesco a farlo funzionare correttamente con più di un singolo comando all'interno del blocco. Nel mio caso, numerosi test hanno rivelato che tutti i comandi all'interno del blocco sono stati memorizzati nella cache e eseguiti simultaneamente alla fine del blocco. Questo ovviamente non produce i risultati attesi. Ecco un esempio semplificato:

if %ERRORLEVEL%==0 (
set var1=blue 
set var2=cheese 
set var3=%var1%_%var2% 
) 

Questo dovrebbe fornire var3 con il seguente valore:

blue_cheese 

ma invece produce:

_ 

perchè tutte 3 comandi vengono memorizzati nella cache ed eseguiti contemporaneamente all'uscita dal blocco di codice.

Sono stato in grado di risolvere questo problema riscrivendo il blocco if per eseguire solo un comando - goto - e aggiungendo alcune etichette. È rozzo, e non mi piace molto, ma almeno funziona.

if %ERRORLEVEL%==0 goto :error0 
goto :endif 

:error0 
set var1=blue 
set var2=cheese 
set var3=%var1%_%var2% 

:endif 
+7

L'utilizzo dell'espansione ritardata deve lavoro: usa: 'set var3 =! var1! _! var2!' – Dracorat

0

Forse un po 'tardi, ma spero che hellps:

@echo off 

if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation... 
goto Continue1 
) 
:Continue1 
If exist "C:\Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation... 
    goto Continue2 
) 
:Continue2 
If exist "C:\Python31\Lib\site-packages\PyQt4" ( 
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation... 
    goto Continue3 
) 
:Continue3 
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation... 
    goto Continue4 
) 
:Continue4 
msg * "Tutto a posto" rem You can relpace msg * with any othe operation... 
pause 
-1

Invece di questo goto pasticcio, provare a utilizzare la e commerciale & o doppio e commerciale & & (condizionale per errorlevel 0) come separatori di comando.

Ho risolto uno snippet di script con questo trucco, per riassumere, ho tre file batch, uno che chiama gli altri due dopo aver trovato le lettere che sono state assegnate alle unità di backup esterne. Lascio il primo file sull'unità esterna primaria in modo che le chiamate alla sua routine di backup funzionino correttamente, ma le chiamate al secondo richiedono una modifica attiva del disco. Il codice qui sotto mostra come ho riparato:

per %% B in (YZ defghijklmnopqrstuvwx) DO ( se esiste "%% B: \ Backup.cmd" %% B: & CALL "%% B: \ Backup .cmd " )

+0

Perché mai è down down? Questo è esattamente ciò di cui avevo bisogno. – ggb667

+0

@ GCB667 - Per chiarire @Louis "ha scritto una" risposta "che non si riferisce al problema del motivo per cui l'istruzione IF non funzionava per il poster originale, in relazione a una risposta di" vinniejohnson "(anche questo ha perso il problema dei poster originali). –

0

Ho trovato questo articolo nei risultati restituiti da una ricerca correlata al comando IF in un file batch e non ho potuto resistere all'opportunità di correggere l'equivoco che i blocchi IF sono limitati a singoli comandi. Di seguito è una parte di uno script di comando di Windows NT di produzione che viene eseguito ogni giorno sulla macchina su cui sto componendo questa risposta.

if "%COPYTOOL%" equ "R" (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*" 
    %TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee 
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Robocopy] %TEMP%\%~n0.TMP %ERRORLEVEL% 
) else (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*" 
    call %TOOLPATH% "%USERPROFILE%\My Documents\Outlook Files\*" "%USERPROFILE%\My Documents\Outlook Files\_backups" /f /m /v /y 
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Xcopy] %TEMP%\%~n0.TMP %ERRORLEVEL% 
) 

Forse blocchi di due o più linee si applica esclusivamente agli script dei comandi di Windows NT (file cmd), perché una ricerca degli script di produzione directory di un'applicazione che è limitato alla vecchia scuola in batch file (bat) , ha rivelato solo blocchi a comando unico. Dal momento che l'applicazione è entrata in manutenzione estesa (il che significa che non sono coinvolto attivamente nel supportarlo), non posso dire se sia perché non avevo bisogno di più di una riga, o che non potevo farle funzionare.

Indipendentemente da ciò, se quest'ultimo è vero, esiste una soluzione semplice; spostare le righe multiple in un file batch separato o in una subroutine del file batch. So che quest'ultimo funziona con entrambi i tipi di script.

Problemi correlati