¿Puedo obtener && para trabajar en Powershell?

186

&&es notoriamente difícil de buscar en google, pero lo mejor que he encontrado es este artículo que dice usar -and.

Desafortunadamente no da más información, y no puedo averiguar con qué debo hacer -and(una vez más, algo muy difícil de buscar)

El contexto en el que intento usarlo es "ejecutar cmd1, y si tiene éxito, ejecutar cmd2", básicamente esto:

csc /t:exe /out:a.exe SomeFile.cs && a.exe

Esto debería ser un simple punto de repetición para alguien que lo sabe, ¡gracias!


Editar: si solo desea ejecutar varios comandos en una sola línea y no le importa si el primero falla o no, puede usar ;Para la mayoría de mis propósitos, está bien

Por ejemplo: kill -n myapp; ./myapp.exe.

Orion Edwards
fuente
PowerShell tiene operadores lógicos -and and -or. ¿Los operadores no están trabajando como usted espera? Si es así, puede publicar la expresión aquí.
Mohit Chakraborty
Vea esta pregunta, hace lo que quiere: stackoverflow.com/questions/1917271/…
joshperry
2
Quien esté interesado en el estilo Bash &&y ||forme parte de PowerShell: vote por la función aquí .
mklement0
1
Con respecto a la necesidad de realizar búsquedas web para consultas con símbolos literales (y significativos): SymbolHound es útil para esto. Aquí hay algunos ejemplos que pertenecen a la pregunta: powershell && ; PowerShell -y . Si usa DuckDuckGo , puede buscar SymbolHound a través de !sym.
nisavid
3
Actualización de junio de 2019 : ¡el equipo de PowerShell está implementando &&y ||! Pesar en el GitHub PR
pilau

Respuestas:

193

En CMD, '&&' significa "ejecutar el comando 1, y si tiene éxito, ejecutar el comando 2". Lo he usado para cosas como:

build && run_tests

En PowerShell, lo más cercano que puede hacer es:

(build) -and (run_tests)

Tiene la misma lógica, pero el texto de salida de los comandos se pierde. Sin embargo, tal vez sea lo suficientemente bueno para ti.

Si está haciendo esto en un script, probablemente sea mejor separar las declaraciones, como esta:

build
if ($?) {
    run_tests
}

27/11 2019 : el &&operador ya está disponible para PowerShell 7 Preview 5+ :

PS > echo "Hello!" && echo "World!"
Hello!
World!
Jay Bazuzi
fuente
2
RE: "ridículo que eliminarían" - No me gusta pensar en PowerShell como "CMD con las partes estúpidas eliminadas". is.gd/k92B
Jay Bazuzi
90
No me gusta pensar en PowerShell como "CMD con las partes estúpidas eliminadas". Me gusta pensar en ello como "Bash sin ninguno de los bits útiles".
Pod
15
También puede hacerlo build ; if ($?) { run_tests }en la línea de comando también.
docwhat
19
La forma más rápida de frustrarse de verdad al aprender PowerShell es comenzar por pensar que es solo un CMD o bash expandido. Tiene un modelo fundamentalmente diferente, especialmente cuando se trata de entrada, salida, tuberías y resultados. Comience con un buen tutorial o descripción general, y no se esfuerce demasiado para que la sintaxis de otros shells funcione. Tienes que tomarlo en sus propios términos.
Mark Meuer
3
Tomando PowerShell en sus propios términos, ¿cómo ejecuto un comando y luego, solo si ese comando tiene éxito, ejecuto otro comando? No creo que eso imponga bashideas en PowerShell. Es la funcionalidad básica del shell. Hasta ahora, lo mejor que he visto es el build ; if ($?) { run_tests }que usaré de ahora en adelante. ¡Espero que el equipo de PowerShell agregue &&soporte!
Nate
28

&& y || estaban en la lista de cosas para implementar (todavía están) pero no aparecieron como la siguiente cosa más útil para agregar. La razón es que tenemos -AND y -OR. Si cree que es importante, presente una sugerencia en Connect y la consideraremos para V3.

Jeffrey Snover - MSFT
fuente
11
Me inscribí en Connect y me nominé para PowerShell, pero no sé cómo hacer una sugerencia. El sitio web de Connect es realmente complejo y confuso :-(
Orion Edwards
66
No pude encontrar una solicitud preexistente, así que hice una: connect.microsoft.com/PowerShell/feedback/details/778798/…
Andy Arismendi
22
Sabes, la pregunta sigue siendo cómo escribir un equivalente, y tu respuesta sería mucho más útil si agregaras un ejemplo de uso -AND
Kyeotic
55
Es importante porque es una herramienta básica de control de flujo utilizada en sistemas más antiguos que Windows por casi la eternidad. Por lo tanto, presenta OTRA diferencia entre Linux y Windows.
airtonix
66
Espero que Jeffrey Snover esté escuchando, este SO debería ser razón suficiente para implementarlo por ahora. Ha pasado demasiado tiempo y ahora PowerShell comienza a aparecer en algunos lugares, como VSCode lo usa como terminal predeterminado en Windows. Este es un dolor total sin &&, se -andcome la salida, no es equivalente en absoluto.
Ciantic
13

Prueba esto:

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe
Ivan
fuente
9
Nota: Si el primer comando falla, el segundo aún se ejecutará.
BrunoLM
44
La variable de preferencia $ErrorActionPreferencesolo gobierna cómo se tratan los errores no terminados informados por los cmdlets ; utilidades externas como cscy a.exenunca informan tales errores (solo reflejan su estado de salida en $?(indicador de éxito) y $LASTEXITCODE(el código de salida específico informado)), por lo que su línea de comando equivale a la ejecución incondicional de ambos comandos (el equivalente de cmd's csc /t:exe /out:a.exe SomeFile.cs & a.exe)
mklement0
5

Si su comando está disponible en cmd.exe (algo así como python ./script.pyno un comando de PowerShell como ii .(Esto significa abrir el directorio actual mediante el explorador)), puede ejecutar cmd.exe dentro de PowerShell. La sintaxis es así:

cmd /c "command1 && command2"

Aquí, &&se proporciona la sintaxis cmd descrita en esta pregunta .

Tomoyuki Aota
fuente
44
Agradable, actualice a cmd para acceder a su funcionalidad adicional.
Bill K
4

Probé esta secuencia de comandos en PowerShell:

Prueba de Fisrt

PS C:\> $MyVar = "C:\MyTxt.txt"
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
True

($MyVar -ne $null)devuelto verdadero y (Get-Content $MyVar)también devuelto verdadero .

Segunda prueba

PS C:\> $MyVar = $null
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
False

($MyVar -ne $null)devuelto falso y hasta ahora debo asumir que (Get-Content $MyVar)también devuelto falso .

La tercera prueba demostró que la segunda condición ni siquiera fue analizada.

PS C:\> ($MyVar -ne $null) -and (Get-Content "C:\MyTxt.txt")
False

($MyVar -ne $null)devolvió falso y demostró que la segunda condición (Get-Content "C:\MyTxt.txt")nunca se ejecutó, al devolver falso en todo el comando.

Cleber Machado
fuente
¡Tienes razón! esto se comporta como el operador &&. ¡Incluso un $ () en el lado derecho no permitirá evaluar esto!
Falco Alexander
2

Pregunta muy antigua, pero para los recién llegados: tal vez la versión de PowerShell (similar pero no equivalente ) que está buscando la pregunta, se use de la -andsiguiente manera:

(build_command) -and (run_tests_command)

Francisco Serrano
fuente
1
Esto puede estar bien para su caso de uso, pero no se comporta como &&, ya que ignora el código de salida de build_command.
Simon Buchan
Esto definitivamente no está haciendo lo correcto. Ejecutará el segundo comando incluso si falla el primero.
Nate
Esto está completamente mal. ;es el equivalente a &en cmd y ;en bash. Definitivamente no es lo mismo que &&en cmd
phuclv
También silencia STDOUT y STDERR para ambos procesos.
Dragas
0

Depende del contexto, pero aquí hay un ejemplo de "-y" en acción:

get-childitem | where-object { $_.Name.StartsWith("f") -and $_.Length -gt 10kb }

Así que se obtienen todos los archivos de más de 10 kb en un directorio cuyo nombre de archivo comienza con "f".

Matt Hamilton
fuente
1
Esta no es una respuesta a la pregunta original, que trata sobre la ejecución de múltiples comandos.
bdukes
0
if (start-process filename1.exe) {} else {start-process filename2.exe}

Es un poco más largo que "&&" pero logra lo mismo sin secuencias de comandos y no es demasiado difícil de recordar. Mejor tarde que nunca. :)

Lydell Anderson
fuente
2
Start-Processes la herramienta incorrecta para invocar utilidades de línea de comandos en general. Específicamente, como se usa aquí, se Start-Processejecuta de filename1.exeforma asíncrona en una nueva ventana de consola y no devuelve nada , lo que en un contexto booleano evalúa $false. Incluso si omitió Start-Process(que es cómo debería invocar directamente a las utilidades de línea de comandos), el enfoque se quedaría corto, porque el resultado del condicional depende de si la utilidad produjo algún resultado estándar, que no tiene una relación garantizada con si exitoso o no.
mklement0
0

Creo que una simple declaración if puede lograr esto. Una vez que vi la respuesta de mkelement0 arriba de que el último estado de salida se almacena en $ ?, puse lo siguiente junto:

# Set 1st command to variable
$a=somecommand

# Temp var to store exit status of last command (since we can't write to $?)
$test=$?

# Run Test
if ($test=$true) { 2nd-command }

Entonces, para el ejemplo de la operación, sería:

a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }
slugman
fuente
0

Un equivalente detallado es combinar $LASTEXITCODEy -eq 0:

msbuild.exe args; if ($LASTEXITCODE -eq 0) { echo 'it built'; } else { echo 'it failed'; }

No estoy seguro de por qué if ($?)no funcionó para mí, pero este sí.

TankorSmash
fuente
-1

Podemos probar este comando en lugar de usar el método &&

intente {hostname; if ($ lastexitcode -eq 0) {ipconfig / all | findtr / i bios}} catch {echo err} finalmente {}

Cyberiron
fuente
No hay necesidad de try/ catch, porque solo es necesario para terminar errores, que utilidades externas como hostname, ipconfigy findstrno pueden desencadenar. La verificación $LASTEXITCODEsolo es necesaria si desea conocer el código de salida específico establecido por una utilidad externa: el éxito o el fracaso abstractos se reflejan $?, al igual que con los cmdlets nativos.
mklement0
Creo que @Cyberiron está en el camino correcto. Creo que &&en Unix se parece mucho a try / catch, ya que no requiere que envuelva los comandos posteriores en un nuevo bloque (es decir }) cuando cortocircuita los comandos posteriores (los omite). Creo que una AmpAmpfunción / filtro que arroje cuándo if (!?) { throw "last command failed" }sería un reemplazo muy útil para portar &&a PowerShell. uso :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
yzorg