Ejecución de comandos en el Shell

PowerShell es un shell de línea de comandos y un lenguaje de scripting, todo en uno. De forma similar a otros shells, como bash en Linux o el shell de comandos de Windows (cmd.exe), PowerShell le permite ejecutar cualquier comando disponible en el sistema, no solo los de PowerShell.

Tipos de comandos

Para cualquier shell de cualquier sistema operativo existen tres tipos de comandos:

  • Las palabras clave del lenguaje del shell forman parte del lenguaje de scripting del shell.

    • Algunos ejemplos de palabras clave de bash son los siguientes: if, then, else, elif y fi.
    • Algunos ejemplos de palabras clave de cmd.exe son los siguientes: dir, copy, move, if y echo.
    • Algunos ejemplos de palabras clave de PowerShell son los siguientes: for, foreach, try, catch y trap.

    Las palabras clave del lenguaje del shell solo se pueden usar en el entorno de tiempo de ejecución del shell. No hay ningún archivo ejecutable externo al shell que proporcione la función de la palabra clave.

  • Los comandos nativos del sistema operativo son archivos ejecutables instalados en el sistema operativo. Los archivos ejecutables se pueden ejecutar desde cualquier shell de línea de comandos, como PowerShell. Esto incluye archivos de script que pueden requerir que otros shells funcionen correctamente. Por ejemplo, si ejecuta un script por lotes de Windows (archivo .cmd) en PowerShell, este ejecuta cmd.exe y pasa el archivo por lotes para su ejecución.

  • Los comandos específicos del entorno del shell son comandos definidos en archivos externos que solo se pueden usar en el entorno de tiempo de ejecución del shell. Estos incluyen scripts y funciones, o pueden ser módulos especialmente compilados que agregan comandos al entorno de ejecución del shell. En PowerShell, estos comandos se conocen como cmdlets (pronunciado "command-lets").

Ejecución de comandos nativos

Cualquier comando nativo se puede ejecutar desde la línea de comandos de PowerShell. Normalmente, el comando se ejecuta exactamente igual que se haría en bash o cmd.exe. En el ejemplo siguiente se muestra cómo ejecutar el comando grep en bash en Ubuntu Linux.

sdwheeler@circumflex:~$ grep sdwheeler /etc/passwd
sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash
sdwheeler@circumflex:~$ pwsh
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

Después de iniciar PowerShell en Ubuntu, puede ejecutar el mismo comando desde la línea de comandos de PowerShell:

PS /home/sdwheeler> grep sdwheeler /etc/passwd
sdwheeler:x:1000:1000:,,,:/home/sdwheeler:/bin/bash

Paso de argumentos a comandos nativos

La mayoría de los shells incluyen características para usar variables, evaluar expresiones y controlar cadenas. Pero cada shell hace estas cosas de manera distinta. En PowerShell, todos los parámetros comienzan con un carácter de guion (-). En cmd.exe, la mayoría de los parámetros usan un carácter de barra diagonal (/). Es posible que otras herramientas de línea de comandos no tengan un carácter especial para los parámetros.

Cada shell tiene su propia manera de controlar y evaluar cadenas en la línea de comandos. Al ejecutar comandos nativos en PowerShell que esperan que las cadenas estén entrecomilladas de forma específica, es posible que necesite ajustar cómo se pasan esas cadenas.

Para más información, consulte los siguientes artículos.

PowerShell 7.2 ha introducido una nueva característica PSnativeCommandArgumentPassing experimental que ha mejorado el control de comandos nativos. Para obtener más información, vea PSnativeCommandArgumentPassing.

Control de la salida y los errores

PowerShell también tiene varios flujos de salida más que otros shells. Los shells bash y cmd.exe tienen stdout y stderr. PowerShell tiene seis flujos de salida. Para obtener más información, vea about_Redirection y about_Output_Streams.

En general, la salida enviada a stdout por un comando nativo se envía a la secuencia Success en PowerShell. La salida enviada a stderr por un comando nativo se envía a la secuencia Erroren PowerShell.

Cuando un comando nativo tiene un código de salida distinto de cero, $? se establece en $false. Si el código de salida es cero, $? se establece en $true.

Pero esto ha cambiado en PowerShell 7.2. Los registros de error redirigidos desde comandos nativos, igual que cuando se usan operadores de redireccionamiento (2>&1), no se escriben en la variable $Error de PowerShell y la variable de preferencia $ErrorActionPreference no afecta a la salida redirigida.

Muchos comandos nativos escriben en stderr a modo de flujo alternativo para obtener información adicional. Este comportamiento puede llevar a confusión en PowerShell cuando se examinan los errores; también, se puede perder la información de salida adicional si $ErrorActionPreference se establece en un estado que silencia la salida.

PowerShell 7.3 ha agregado una nueva característica PSnativeCommandErrorActionPreference experimental que le permite controlar si la salida a stderr se trata como un error. Para obtener más información, vea PSnativeCommandErrorActionPreference.

Ejecución de comandos de PowerShell

Tal como se ha indicado anteriormente, los comandos de PowerShell se conocen como cmdlets. Los cmdlets se recopilan en módulos de PowerShell que se pueden cargar a petición. Los cmdlets se pueden escribir en cualquier lenguaje .NET compilado o con el mismo lenguaje de scripting de PowerShell.

Comandos de PowerShell que ejecutan otros comandos

El operador de llamada de PowerShell (&) permite ejecutar comandos almacenados en variables y que representan cadenas o bloques de script. Puede usarlo para ejecutar cualquier comando nativo o de PowerShell. Esto es útil en un script cuando necesita construir dinámicamente los parámetros de la línea de comandos para un comando nativo. Para obtener más información, vea el operador de llamada.

El cmdlet Start-Process se puede usar para ejecutar comandos nativos, pero solo debe usarse cuando necesite controlar cómo se ejecuta el comando. El cmdlet tiene parámetros para admitir los escenarios siguientes:

  • Ejecución de un comando con credenciales diferentes
  • Ocultación de la ventana de consola que ha creado el proceso nuevo
  • Redirección de los flujos stdin, stdout y stderr
  • Uso de otro directorio de trabajo para el comando

En el ejemplo siguiente se ejecuta el comando nativo sort.exe con flujos de entrada y salida redirigidos.

$processOptions = @{
    FilePath = "sort.exe"
    RedirectStandardInput = "TestSort.txt"
    RedirectStandardOutput = "Sorted.txt"
    RedirectStandardError = "SortError.txt"
    UseNewEnvironment = $true
}
Start-Process @processOptions

Para obtener más información, vea Start-Process.

En Windows, el cmdlet Invoke-Item realiza la acción predeterminada para el elemento especificado. Por ejemplo, ejecuta un archivo ejecutable o abre un archivo de documento con la aplicación asociada al tipo de archivo del documento. La acción predeterminada depende del tipo de elemento y la resuelve el proveedor de PowerShell que proporciona acceso al elemento.

En el ejemplo siguiente se abre el repositorio de código fuente de PowerShell en el explorador web predeterminado.

Invoke-Item https://github.com/PowerShell/PowerShell

Para obtener más información, vea Invoke-Item.