batch-file utilità - Come posso eseguire due comandi su una riga in Windows CMD?




stringhe pc (14)

Una citazione dalla documentazione:

Utilizzo di più comandi e simboli di elaborazione condizionale

È possibile eseguire più comandi da una singola riga di comando o uno script utilizzando i simboli di elaborazione condizionale. Quando si eseguono più comandi con simboli di elaborazione condizionale, i comandi a destra del simbolo di elaborazione condizionale agiscono in base ai risultati del comando a sinistra del simbolo di elaborazione condizionale.

Ad esempio, è possibile eseguire un comando solo se il comando precedente non riesce. Oppure, potresti voler eseguire un comando solo se il comando precedente ha avuto successo.

È possibile utilizzare i caratteri speciali elencati nella seguente tabella per passare più comandi.

  • & [...]
    command1 & command2
    Utilizzare per separare più comandi su una riga di comando. Cmd.exe esegue il primo comando e quindi il secondo comando.

  • && [...]
    command1 && command2
    Utilizzare per eseguire il comando seguendo && solo se il comando che precede il simbolo ha esito positivo. Cmd.exe esegue il primo comando e quindi esegue il secondo comando solo se il primo comando è stato completato correttamente.

  • || [...]
    command1 || command2
    Utilizzare per eseguire il comando seguente || solo se il comando precedente || non riesce. Cmd.exe esegue il primo comando e quindi esegue il secondo comando solo se il primo comando non è stato completato correttamente (riceve un codice di errore maggiore di zero).

  • ( ) [...]
    (command1 & command2)
    Utilizzare per raggruppare o nidificare più comandi.

  • ; or ,
    command1 parameter1;parameter2
    Utilizzare per separare i parametri di comando.

Voglio eseguire due comandi in una console CMD Windows.

In Linux lo farei così

touch thisfile ; ls -lstrh

Come è fatto su Windows?


Quindi, stavo cercando di abilitare l'attività specifica di esecuzione di RegAsm (registro assembly) da un menu di scelta rapida. Il problema che ho avuto è stato che il risultato si sarebbe rivelato e se ne sarebbe andato prima che potessi leggerlo. Così ho provato il piping in Pause , che non funziona quando il comando fallisce (come menzionato qui il comando Pause non funziona nello script .bat e qui il comando del file batch PAUSE non funziona ). Così ho provato cmd /k ma questo lascia la finestra aperta per altri comandi (voglio solo leggere il risultato). Così ho aggiunto una pause seguita exit dalla catena, con il risultato di:

cmd /k C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe "%1" /codebase \"%1\" & pause & exit

Funziona come un incantesimo: RegAsm viene eseguito sul file e mostra i risultati, quindi viene visualizzato il prompt "Premere un tasto qualsiasi per continuare ...", quindi la finestra del prompt dei comandi si chiude quando viene premuto un tasto.

PS Per gli altri che potrebbero essere interessati, è possibile utilizzare le seguenti voci di file .reg per aggiungere un'associazione dllfile ai file dll e quindi un'estensione di comando RegAsm a tale (notare le virgolette e le barre rovesciate di escape):

[HKEY_CLASSES_ROOT\.dll]
"Content Type"="application/x-msdownload"
@="dllfile"

[HKEY_CLASSES_ROOT\dllfile]
@="Application Extension"

[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm]
@="Register Assembly"

[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm\command]
@="cmd /k C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\regasm.exe \"%1\" /codebase \"%1\" & pause & exit"

Ora ho un bel menu di scelta rapida per registrare un assembly.


È possibile utilizzare un numero di simboli di elaborazione quando si eseguono più comandi sulla stessa linea e, in alcuni casi, può essere necessario elaborare il reindirizzamento, alterando l'output in altri casi o semplicemente fallendo. Un caso importante è mettere sulla stessa riga i comandi che manipolano le variabili.

@echo off
setlocal enabledelayedexpansion
set count=0
set "count=1" & echo %count% !count!

0 1

Come si vede nell'esempio precedente, quando i comandi che utilizzano le variabili sono posizionati sulla stessa riga, è necessario utilizzare l'espansione ritardata per aggiornare i valori delle variabili. Se la tua variabile è indicizzata, usa il comando CALL con i modificatori %% per aggiornare il suo valore sulla stessa riga:

set "i=5" & set "arg!i!=MyFile!i!" & call echo path!i!=%temp%\%%arg!i!%%

path5=C:\Users\UserName\AppData\Local\Temp\MyFile5

Un altro esempio: ad esempio, quando usiamo il sistema gulp , invece di

gulp - default> build

gulp build - build build-folder

gulp watch - avvia il file-watch

gulp dist - build dist-folder

Possiamo farlo con una riga:

cd c:\xampp\htdocs\project & gulp & gulp watch

cmd /c ipconfig /all & Output.txt

Questo comando esegue il comando e apre il file Output.txt in un unico comando


Per eseguire due comandi contemporaneamente, devi inserire un simbolo & (commerciale) tra i due comandi. Così:

color 0a & start chrome.exe

Saluti!


È semplice: basta differenziarli con i segni &&. Esempio:

echo Hello World && echo GoodBye World

Goodbye World verrà stampato dopo Hello World.


& è l'equivalente di Bash per ; (esegui i comandi) e && è l'equivalente Bash di && (esegui i comandi solo quando il precedente non ha causato un errore).


No, cd / && tree && echo %time% . Il tempo di eco è quando viene eseguito il primo comando.

Le tubazioni hanno qualche problema, ma non è fondamentale finché le persone sanno come funziona.


Puoi usare & per eseguire i comandi uno dopo l'altro. Esempio: c:\dir & vim myFile.txt


Provo ad avere due ping nella stessa finestra, ed è un comando seriale sulla stessa linea. Dopo aver terminato il primo, esegui il secondo comando.

La soluzione era combinare con start /b su un prompt dei comandi di Windows 7.

Inizia come al solito, senza /b , e avvia in una finestra separata.

Il comando utilizzato per l'avvio nella stessa riga è:

start /b command1 parameters & command2 parameters

In ogni caso, se si desidera analizzare l'output, non è consigliabile utilizzarlo. Ho notato che l'output è codificato tra l'output dei comandi.


Bene, hai due opzioni: Piping, o solo & :

DIR /S & START FILE.TXT

O,

tasklist | find "notepad.exe"

Piping ( | ) è più per prendere l'output di un comando e metterlo in un altro. E ( & ) sta solo dicendo di farlo, e quello.


Quando cerchi di utilizzare o manipolare le variabili in una riga, fai attenzione ai loro contenuti! Ad esempio una variabile come la seguente

PATH=C:\Program Files (x86)\somewhere;"C:\Company\Cool Tool";%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;

può portare a un sacco di guai sfortunati se lo usi come %PATH%

  1. Le parentesi di chiusura terminano la tua dichiarazione di gruppo
  2. Le virgolette non ti permettono di usare %PATH% per gestire il problema delle parentesi
  3. E cosa contiene una variabile referenziata come %USERPROFILE% ?

Non so se questo aiuta. Inserito come risposta perché non so come formattare il codice nei commenti (help?)

Se riesci a trovare un compilatore pascal gratuito, puoi compilarlo o mandarmi una e-mail e posso provare a cercarne uno, o spedire per posta l'exe o postarlo da qualche parte. Inserisco il codice, per quanto sia cattivo, perché almeno funziona e mostra l'algoritmo necessario.

program Whence (input,output);
  Uses Dos, my_funk;
  Const program_version = '1.00';
        program_date    = '17 March 1994';
  VAR   path_str          : string;
        command_name      : NameStr;
        command_extension : ExtStr;
        command_directory : DirStr;
        search_dir        : DirStr;
        result            : DirStr;


  procedure Check_for (file_name : string);
    { check existance of the passed parameter. If exists, then state so   }
    { and exit.                                                           }
  begin
    if Fsearch(file_name,'') <> '' then
    begin
      WriteLn('Dos command = ',Fexpand(file_name));
      Halt(0);    { structured ? whaddayamean structured ? }
    end;
  end;

  function Get_next_dir : DirStr;
    { Returns the next directory from the path variable, truncating the   }
    { variable every time. Implicit input (but not passed as parameter)   }
    { is, therefore, path_str                                             }
    var  semic_pos  : Byte;

  begin
      semic_pos  := Pos(';',path_str);
      if (semic_pos = 0) then
      begin
        Get_next_dir := '';
        Exit;
      end;

      result       := Copy(Path_str,1,(semic_pos - 1));  { return result   }
      { hmm! although *I* never reference a Root drive (my directory tree) }
      { is 1/2 way structured), some network logon software which I run    }
      { does (it adds Z:\ to the path). This means that I have to allow    }
      { path entries with & without a terminating backslash. I'll delete   }
      { anysuch here since I always add one in the main program below.     }
      if (Copy(result,(Length(result)),1) = '\') then
         Delete(result,Length(result),1);

      path_str     := Copy(path_str,(semic_pos + 1),
                                 (length(path_str) - semic_pos));
      Get_next_dir := result;
  end;  { of function get_next_dir }

begin
  { the following is a kludge which makes the function Get_next_dir easier  }
  { to implement. By appending a semi-colon to the end of the path         }
  { Get_next_dir doesn't need to handle the special case of the last entry }
  { which normally doesn't have a semic afterwards. It may be a kludge,    }
  { but it's a documented kludge (you might even call it a refinement).    }
  path_str := GetEnv('Path') + ';';

  if (paramCount = 0) then
  begin
    WriteLn('Whence : V',program_version,' from ',program_date);
    Writeln;
    WriteLn('Usage  : WHENCE command[.extension]');
    WriteLn;
    WriteLn('Whence is a ''find file''type utility witha difference');
    Writeln('There are are already more than enough of those   :-)');
    Write  ('Use Whence when you''re not sure where a command which you ');
    WriteLn('want to invoke');
    WriteLn('actually resides.');
    Write  ('If you intend to invoke the command with an extension e.g ');
    Writeln('"my_cmd.exe param"');
    Write  ('then invoke Whence with the same extension e.g ');
    WriteLn('"Whence my_cmd.exe"');
    Write  ('otherwise a simple "Whence my_cmd" will suffice; Whence will ');
    Write  ('then search the current directory and each directory in the ');
    Write  ('for My_cmd.com, then My_cmd.exe and lastly for my_cmd.bat, ');
    Write  ('just as DOS does');
    Halt(0);
  end;

  Fsplit(paramStr(1),command_directory,command_name,command_extension);
  if (command_directory <> '') then
  begin
WriteLn('directory detected *',command_directory,'*');
    Halt(0);
  end;

  if (command_extension <> '') then
  begin
    path_str := Fsearch(paramstr(1),'');    { current directory }
    if   (path_str <> '') then WriteLn('Dos command = "',Fexpand(path_str),'"')
    else
    begin
      path_str := Fsearch(paramstr(1),GetEnv('path'));
      if (path_str <> '') then WriteLn('Dos command = "',Fexpand(path_str),'"')
                          else Writeln('command not found in path.');
    end;
  end
  else
  begin
    { O.K, the way it works, DOS looks for a command firstly in the current  }
    { directory, then in each directory in the Path. If no extension is      }
    { given and several commands of the same name exist, then .COM has       }
    { priority over .EXE, has priority over .BAT                             }

    Check_for(paramstr(1) + '.com');     { won't return if file is found }
    Check_for(paramstr(1) + '.exe');
    Check_for(paramstr(1) + '.bat');


    { not in current directory, search thru path .... }

    search_dir := Get_next_dir;

    while (search_dir <> '') do
    begin
       Check_for(search_dir + '\' + paramstr(1) + '.com');
       Check_for(search_dir + '\' + paramstr(1) + '.exe');
       Check_for(search_dir + '\' + paramstr(1) + '.bat');
       search_dir := Get_next_dir;
    end;


    WriteLn('DOS command not found : ',paramstr(1));
  end;
end.




windows batch-file command-line cmd