2009-12-16 7 views
7

Me pregunto si alguien sabe de una manera de ejecutar un programa condicional en función del éxito de salida/fracaso del programa anterior. ¿Hay alguna forma de que ejecute un programa2 inmediatamente después del programa1 si el programa1 finaliza exitosamente sin probar la variable LASTEXITCODE? Probé la banda y los operadores en vano, aunque tenía la sensación de que no funcionarían de todos modos, y el mejor sustituto es una combinación de un punto y coma y una declaración if. Es decir, cuando se trata de la construcción de un paquete de algo de forma automática desde las fuentes en Linux, el operador & & no puede ser mejor:proceso de ejecución condicional en Windows PowerShell (por ejemplo, el && y || operadores en Bash)

# Configure a package, compile it and install it 
./configure && make && sudo make install 

PowerShell me exigiría a hacer lo siguiente, suponiendo que en realidad podría utilizar el mismo sistema de construcción en PowerShell:

# Configure a package, compile it and install it 
.\configure ; if ($LASTEXITCODE -eq 0) { make ; if ($LASTEXITCODE -eq 0) { sudo make install } } 

Claro, yo podría utilizar múltiples líneas, lo guarda en un archivo y ejecutar la secuencia de comandos, pero la idea es para que sea concisa (salvo las pulsaciones del teclado). Quizás es sólo una diferencia entre PowerShell y Bash (e incluso la incorporada en el símbolo del sistema de Windows que soporta el operador & &) Voy a tener que adaptarse a, pero si hay una forma más limpia de hacerlo, me gustaría saber .

+0

Quien esté interesado en '' && 'y' || 'de Bash-style formando parte de PowerShell: vote por la función [aquí] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087898-implement-the-and-operators-that-bash-has). – mklement0

Respuesta

2

Se puede crear una función para hacer esto, pero no hay una forma directa de hacerlo, que yo sepa.

function run-conditionally($commands) { 
    $ranAll = $false 
    foreach($command in $commands) { 
     invoke-command $command 
     if ($LASTEXITCODE -ne 0) { 
      $ranAll = $false 
      break; 
     } 
     $ranAll = $true 
    } 

    Write-Host "Finished: $ranAll" 

    return $ranAll 
} 

Entonces llaman similar a

run-conditionally(@(".\configure","make","sudo make install")) 

Probablemente hay algunos errores allí esto es fruto de la casualidad y sin un entorno de PowerShell práctico.

+0

Lo modificaré para que funcione (Invocar-Expresión es necesaria porque Invoke-Command aparentemente no funciona como debería ... o algo así), pero definitivamente es algo útil. Gracias por la ayuda. Es muy apreciado. – Dustin

+3

El problema con el uso de '$ LASTEXITCODE' es que solo se establece cuando PowerShell ejecuta un EXE de consola. Puede ser mejor que uses '$?'. –

+0

Puede alias esa función para que sea más fácil invocarla. – GrayWizardx

0

estaba realmente sufriendo por la falta de & &, también, así que escribió el guión siguiente sencillo basado en la respuesta de GrayWizardX (que no funciona como está):

foreach($command in $args) 
{ 
    $error.clear() 
    invoke-command $command 
    if ($error) { break; } 
} 

Si lo guarda como rc.ps1 (para "ejecutar de forma condicional") en un directorio en su camino, se puede usar como:

rc {.\configure} {make} {make install} 

el uso de bloques de script (las llaves) como argumentos en lugar de cadenas significa que puede utilizar la implementación del tabulador mientras escribiendo los comandos, que es muc h más agradable. Este script es casi tan bueno como & &, y funciona.

+1

Además, cambiar la cuarta línea a 'if ($?) {Break; } 'hace que el script se comporte como ||, en caso de que no fuera obvio. – Abram

+0

No es una buena idea _clear_ la colección '$ Error'; la prueba '$?' hará ('if ($?) {break}' para '&&', y 'if (-not $?) {break}' para '||'). Para usar 'Invoke-Command', debe pasar un _script block_, así que es mejor escribir el parámetro' $ args' de esa manera: '[scriptblock []] $ args'. Además, para evitar los efectos secundarios, use 'Invoke-Command -NoNewScope' - o simplemente use el operador' .'. – mklement0

Cuestiones relacionadas