Sto eseguendo un file batch a esecuzione prolungata. Ora mi rendo conto che devo aggiungere altri comandi alla fine del file batch (nessuna modifica al contenuto esistente, solo alcuni comandi extra). È possibile farlo, dato che la maggior parte dei file batch vengono letti in modo incrementale ed eseguiti uno per uno? O il sistema legge l'intero contenuto del file e quindi esegue il lavoro?Modifica di un file batch quando è in esecuzione
risposta
ho appena provato, e contro la mia intuizione, che raccolse i nuovi comandi alla fine (su Windows XP)
ho creato un file batch che contiene
echo Hello
pause
echo world
ho eseguito il file, e mentre era in pausa, ha aggiunto
echo Salute
salvato e premuto Invio per proseguire, la pausa, tutte e tre le richieste hanno fatto eco alla console.
Quindi, prendilo!
L'interprete dei comandi ricorda la posizione della linea nel file batch. Finché si modifica il file batch dopo la posizione corrente della linea di esecuzione, tutto andrà bene.
Se lo modifichi prima, inizierà a fare cose strane (comandi ripetuti ecc.).
È documentato ovunque, per favore, o è questo dalla tua stessa esperienza? – Benoit
Questo è vero nella mia esperienza. – UnhandledExcepSean
In realtà, ciò che farà è che il puntatore del parser rimarrà allo stesso indice nel file, quindi aggiungendo/rimuovendo il testo prima che l'indice sposterà ciò che è sotto il puntatore dell'istruzione. Succedono cose strane, davvero. – cat
Quasi come rein ha detto, cmd.exe ricorda la posizione del file (non solo la posizione della linea) che è attualmente, e anche per ogni chiamata spinge la posizione del file su uno stack invisibile.
Ciò significa, è possibile modificare il file mentre è in esecuzione dietro e davanti la posizione di file effettivo, è necessario solo quello che fai ...
Un piccolo campione di un lotto automodificante
cambia la linea set value=1000
esempio continuamente
@echo off
setlocal DisableDelayedExpansion
:loop
REM **** the next line will be changed
set value=1000
rem ***
echo ----------------------
echo The current value=%value%
<nul set /p ".=Press a key"
pause > nul
echo(
(
call :changeBatch
rem This should be here and it should be long
)
rem ** It is neccessary, that this is also here!
goto :loop
rem ...
:changeBatch
set /a n=0
set /a newValue=value+1
set /a toggle=value %% 2
set "theNewLine=set value=%newValue%"
if %toggle%==0 (
set "theNewLine=%theNewLine% & rem This adds 50 byte to the filesize.........."
)
del "%~f0.tmp" 2> nul
for /F "usebackq delims=" %%a in ("%~f0") DO (
set /a n+=1
set "line=%%a"
setlocal EnableDelayedExpansion
if !n!==5 (
(echo !theNewLine!)
) ELSE (
(echo !line!)
)
endlocal
) >> "%~f0.tmp"
(
rem the copy should be done in a parenthesis block
copy "%~f0.tmp" "%~f0" > nul
if Armageddon==TheEndOfDays (
echo This can't never be true, or is it?
)
)
echo The first line after the replace action....
echo The second line comes always after the first line?
echo The current filesize is now %~z0
goto :eof
+1 Questo è un divertente esempio di ciò che è possibile :) – dbenham
di Jeb è molto divertente, ma è molto dipendente dalla lunghezza del testo che viene aggiunto o eliminato. Penso che i risultati contro-intuitivi siano ciò che intendeva dire quando ha detto "Se lo modifichi prima inizierà a fare cose strane (comandi ripetuti ecc.)".
Ho modificato il codice di jeb per mostrare in che modo il codice dinamico di lunghezza variabile può essere modificato liberamente all'inizio di un file batch in esecuzione purché sia inserito il riempimento appropriato. L'intera sezione dinamica è completamente sostituita da ogni iterazione. Ogni linea dinamica è preceduta da un prefisso non interferente ;
. Ciò consente comodamente a FOR /F
di rimuovere il codice dinamico a causa dell'opzione implicita EOL=;
.
Invece di cercare un particolare numero di riga, cerco un commento specifico per individuare dove inizia il codice dinamico. Questo è più facile da mantenere.
Uso linee di uguale segno per riempire in modo innocuo il codice per consentire espansione e contrazione. È possibile utilizzare qualsiasi combinazione dei seguenti caratteri: virgola, punto e virgola, uguale, spazio, scheda e/o nuova riga. (Ovviamente il padding non può iniziare con un punto e virgola). I segni di uguale all'interno delle parentesi consentono l'espansione del codice. I segni di uguale dopo le parentesi consentono la contrazione del codice.
Si noti che FOR /F
strisce righe vuote.Questa limitazione potrebbe essere superata utilizzando FINDSTR per prefissare ciascuna riga con il numero di riga e quindi rimuovere il prefisso all'interno del ciclo. Ma il codice extra rallenta le cose, quindi non vale la pena farlo a meno che il codice non dipenda da linee vuote.
@echo off
setlocal DisableDelayedExpansion
echo The starting filesize is %~z0
:loop
echo ----------------------
::*** Start of dynamic code ***
;set value=1
::*** End of dynamic code ***
echo The current value=%value%
::
::The 2 lines of equal signs amount to 164 bytes, including end of line chars.
::Putting the lines both within and after the parentheses allows for expansion
::or contraction by up to 164 bytes within the dynamic section of code.
(
call :changeBatch
==============================================================================
==============================================================================
)
================================================================================
================================================================================
set /p "quit=Enter Q to quit, anything else to continue: "
if /i "%quit%"=="Q" exit /b
goto :loop
:changeBatch
(
for /f "usebackq delims=" %%a in ("%~f0") do (
echo %%a
if "%%a"=="::*** Start of dynamic code ***" (
setlocal enableDelayedExpansion
set /a newValue=value+1, extra=!random!%%9
echo ;set value=!newValue!
for /l %%n in (1 1 !extra!) do echo ;echo extra line %%n
endlocal
)
)
) >"%~f0.tmp"
::
::The 2 lines of equal signs amount to 164 bytes, including end of line chars.
::Putting the lines both within and after the parentheses allows for expansion
::or contraction by up to 164 bytes within the dynamic section of code.
(
move /y "%~f0.tmp" "%~f0" > nul
==============================================================================
==============================================================================
)
================================================================================
================================================================================
echo The new filesize is %~z0
exit /b
I lavori di cui sopra, ma le cose sono molto più facile se il codice dinamico viene spostato in una subroutine alla fine del file. Il codice può espandersi e contrarsi senza limitazioni e senza necessità di riempimento. FINDSTR è molto più veloce di FOR/F nella rimozione della porzione dinamica. Le linee dinamiche possono essere tranquillamente precedute da un punto e virgola (comprese le etichette!). Quindi l'opzione FINDSTR/V viene utilizzata per escludere le righe che iniziano con un punto e virgola e il nuovo codice dinamico può essere semplicemente aggiunto.
@echo off
setlocal DisableDelayedExpansion
echo The starting filesize is %~z0
:loop
echo ----------------------
call :dynamicCode1
call :dynamicCode2
echo The current value=%value%
call :changeBatch
set /p "quit=Enter Q to quit, anything else to continue: "
if /i "%quit%"=="Q" exit /b
goto :loop
:changeBatch
(
findstr /v "^;" "%~f0"
setlocal enableDelayedExpansion
set /a newValue=value+1, extra=!random!%%9
echo ;:dynamicCode1
echo ;set value=!newValue!
echo ;exit /b
echo ;
echo ;:dynamicCode2
for /l %%n in (1 1 !extra!) do echo ;echo extra line %%n
echo ;exit /b
endlocal
) >"%~f0.tmp"
move /y "%~f0.tmp" "%~f0" > nul
echo The new filesize is %~z0
exit /b
;:dynamicCode1
;set value=33
;exit /b
;
;:dynamicCode2
;echo extra line 1
;exit /b
EDIT - Ho modificato l'ultimo codice per dimostrare che anche le etichette possono essere prefissate, in modo che possano essere facilmente incluse nel codice dinamico. – dbenham
Risposta breve: sì, i file batch possono modificarsi durante l'esecuzione. Come altri hanno già confermato.
Anni e anni fa, prima che Windows 3, il posto ho lavorato aveva un sistema di menu inhouse in MS-DOS. Il modo in cui gestiva le cose era abbastanza elegante: in realtà veniva eseguito da un file batch che il programma principale (scritto in C) è stato modificato per poter eseguire gli script. Questo trucco significava che il programma di menu non occupava spazio nella memoria mentre le selezioni erano in esecuzione. E questo includeva cose come il programma LAN Mail e il programma del terminale 3270.
Ma l'esecuzione da un file batch auto-modificante implicava che i suoi script potevano anche fare cose come caricare programmi TSR e in effetti potevano fare praticamente tutto ciò che si poteva inserire in un file batch. Il che ha reso molto potente. Solo il comando GOTO
non ha funzionato, fino a quando l'autore non ha capito come rendere il file batch riavviato da solo per ogni comando.
L'interprete dei comandi sembra ricordare l'offset di byte all'interno di ogni file di comando che sta leggendo, ma il file stesso non è bloccato, quindi è possibile apportare modifiche, ad esempio con un editor di testo, mentre è in esecuzione.
Se viene apportata una modifica al file dopo questa posizione ricordato, l'interprete dovrebbe felicemente continuare a eseguire lo script ora modificato. Tuttavia, se la modifica viene apportata prima di quel punto e tale modifica modifica la lunghezza del testo in quel punto (ad esempio, hai inserito o rimosso del testo), quella posizione memorizzata ora non si riferisce più all'inizio di quel prossimo comando . Quando l'interprete prova a leggere la "linea" successiva, prenderà invece una linea diversa, o forse parte di una linea, a seconda di quanto testo è stato inserito o rimosso. Se sei fortunato, probabilmente non sarà in grado di elaborare qualsiasi parola su cui è successo, dare un errore e continuare ad eseguire dalla riga successiva - ma probabilmente non è quello che vuoi.
Tuttavia, con la comprensione di quello che sta succedendo, è possibile strutturare gli script per ridurre il rischio. Ho degli script che implementano un semplice sistema di menu, visualizzando un menu, accettando input dall'utente utilizzando il comando choice
e quindi elaborando la selezione. Il trucco consiste nel garantire che il punto in cui lo script attende l'input sia vicino alla parte superiore del file, in modo che tutte le modifiche che potresti voler apportare si verifichino dopo quel punto e quindi non abbiano impatti sgradevoli.
Esempio:
:top
call :displayMenu
:prompt
REM The script will spend most of its time waiting here.
choice /C:1234 /N "Enter selection: "
if ERRORLEVEL == 4 goto DoOption4
if ERRORLEVEL == 3 goto DoOption3
if ERRORLEVEL == 2 goto DoOption2
goto DoOption1
:displayMenu
(many lines to display menu)
goto prompt
:DoOption1
(many lines to do Option 1)
goto top
:DoOption2
(many lines to do Option 2)
goto top
(etc)
- 1. Modifica file Jar in esecuzione
- 2. Esecuzione di un file batch nella shell git
- 3. Includere un file batch in un file batch
- 4. esecuzione di file batch di Windows comandi in modo asincrono
- 5. Esecuzione di file batch da JScript in HTA
- 6. come dire su quale versione di windows e/o cmd.exe è in esecuzione un file batch?
- 7. Quando è stato creato Batch?
- 8. Esecuzione del file batch nel programma di installazione NSIS
- 9. Il file batch in esecuzione in Utilità di pianificazione continua a essere eseguito dopo il completamento del file batch
- 10. Controllo di ritorno da un file batch
- 11. esecuzione grunt ferma script batch
- 12. Esecuzione di un file batch in una data directory utilizzando VBA
- 13. Menu in file batch
- 14. esecuzione di un comando batch tramite processo SSIS
- 15. Modifica di un file di grandi dimensioni in Scala
- 16. File .bat in esecuzione da TeamCity
- 17. Eseguire un file batch in una nuova finestra dal batch?
- 18. Errore in un file batch chiamato
- 19. Finestra PowerShell quando avviata da un file batch
- 20. Modifica di un file in un barattolo
- 21. Batch/Trova e modifica righe nel file TXT
- 22. Modifica della variabile di ambiente di un processo in esecuzione
- 23. subroutine in file batch
- 24. Cosa significa% * in un file batch
- 25. Come sovrascrivere un file di testo da un file batch
- 26. File batch: maschera file
- 27. Modifica dell'ordine di esecuzione del plugin Maven
- 28. Modifica oggetto iniettato in fase di esecuzione
- 29. chiede AppleID quando è in esecuzione
- 30. BroadcastReceiver quando l'applicazione non è in esecuzione
che ami devi risposte così veloce. Hai già iniziato a eseguire il batch> ha postato una domanda> hai ottenuto una risposta> hai modificato il tuo file prima che l'esecuzione fosse completata! –
Si noti inoltre che quando il file batch viene rimosso o rinominato, nel momento in cui l'istruzione corrente ha terminato, viene generato un errore: "Impossibile trovare il file batch". –