Compartir a través de


acerca de Parsing

Descripción breve

Describe cómo PowerShell analiza los comandos.

Descripción larga

Cuando introduces un comando en el símbolo del sistema, PowerShell divide el texto del comando en una serie de segmentos llamados tokens y luego determina cómo interpretar cada token.

Por ejemplo, si escribe:

Write-Host book

PowerShell divide el comando en dos tokens, Write-Host y book, e interpreta cada token de forma independiente mediante uno de los dos modos de análisis principales: modo de expresión y modo de argumento.

Nota:

A medida que PowerShell analiza la entrada del comando, intenta resolver los nombres de comando en cmdlets o ejecutables nativos. Si un nombre de comando no tiene una coincidencia exacta, PowerShell antepone Get- al comando como verbo predeterminado. Por ejemplo, PowerShell analiza Process como Get-Process. No se recomienda usar esta característica por los siguientes motivos:

  • Es ineficaz. Esto hace que PowerShell busque varias veces.
  • Los programas externos con el mismo nombre se resuelven primero, por lo que no es posible que ejecute el cmdlet previsto.
  • Get-Help y Get-Command no reconocen nombres sin verbo.

Modo de expresión

El modo de expresión está diseñado para combinar expresiones, necesarias para la manipulación de valores en un lenguaje de scripting. Las expresiones son representaciones de valores en la sintaxis de PowerShell y pueden ser simples o compuestas, por ejemplo:

Las expresiones literales son representaciones directas de sus valores:

'hello'
32

Las expresiones de variable llevan el valor de la variable a la que hacen referencia:

$x
$script:path

Los operadores combinan otras expresiones para la evaluación:

-12
-not $Quiet
3 + 7
$input.Length -gt 1
  • Las cadenas de caracteres literales deben ir entre comillas.
  • Los números se tratan como valores numéricos y no como una serie de caracteres (a menos que se escapen).
  • Operadores, incluidos los operadores unarios como - y -not, y los operadores binarios como + y -gt, se interpretan como operadores y aplican sus respectivas operaciones a sus argumentos (operandos).
  • Las expresiones de atributo y conversión se analizan como expresiones y se aplican a expresiones subordinadas, p. ej. [int] '7'.
  • Las referencias de variables se evalúan según sus valores, pero el splatting (es decir, el pegado de conjuntos de parámetros precargados) está prohibido y provoca un error del analizador.
  • Cualquier otra cosa se tratará como un comando que se invocará.

Modo de argumento

Al analizar, PowerShell primero busca interpretar la entrada como una expresión. Pero cuando se encuentra una invocación de comando, el análisis continúa en modo de argumento. Si tiene argumentos que contienen espacios, como rutas de acceso, debe incluir esos valores de argumento entre comillas.

El modo de argumento está diseñado para analizar argumentos y parámetros para comandos en un entorno de shell. Toda la entrada se trata como una cadena expandible a menos que use una de las sintaxis siguientes:

  • El signo de dólar ($) seguido de un nombre de variable comienza una referencia de variable, de lo contrario, se interpreta como parte de la cadena expandible. La referencia a una variable puede incluir un acceso a un miembro o un índice.

    • Los caracteres adicionales siguientes a referencias de variables simples, como $HOME, se consideran parte del mismo argumento. Incluya el nombre de la variable entre llaves ({}) para separarlo de los caracteres posteriores. Por ejemplo: ${HOME}.
    • Cuando la referencia de variable incluye el acceso a miembros, el primero de los caracteres adicionales se considera el comienzo de un nuevo argumento. Por ejemplo $HOME.Length-more da como resultado dos argumentos: el valor de $HOME.Length y el literal de cadena -more.
  • Las comillas (' y ") inician las cadenas de caracteres

  • Los corchetes ({}) inician un nuevo bloque de script

  • Las comas (,) introducen listas pasadas como matrices, excepto cuando el comando que se va a llamar es una aplicación nativa, en cuyo caso se interpretan como parte de la cadena expandible. No se admiten comas iniciales, consecutivas o finales.

  • Paréntesis (()) comienzan una nueva expresión

  • Operador de subexpresión ($()) que inicia una expresión embebida.

  • Inicial en signo (@) comienza sintaxis de expresión como la expansión (), matrices (@args@(1,2,3)) y literales de tabla hash (@{a=1;b=2}).

  • (), $()y @() al comienzo de un token crean un nuevo contexto de análisis que puede contener expresiones y/o comandos anidados.

    • Cuando va seguido de caracteres adicionales, el primer carácter adicional se considera el inicio de un nuevo argumento independiente.
    • Cuando va precedido de un literal $() sin comillas, funciona como una cadena expandible, () inicia un nuevo argumento que es una expresión y @() se toma como literal @ con () el inicio de un nuevo argumento que es una expresión.
  • Todo lo demás se trata como una cadena expandible, excepto los metacaracteres, que aún necesitan escaparse.

    • Los metacaractores en modo de argumento (caracteres con significado sintáctico especial) son: <space> ' " ` , ; ( ) { } | & < > @ #. De estos, < > @ # solo son especiales al principio de un token.
  • El token de interrupción del análisis (--%) cambia la interpretación de todos los argumentos restantes. Para obtener más información, consulte la sección sobre los tokens de parada.

Ejemplos

En la tabla siguiente se proporcionan varios ejemplos de tokens procesados en modo de expresión y modo de argumento y la evaluación de esos tokens. Para estos ejemplos, el valor de la variable $a es 4.

Ejemplo Modo Resultado
2 Expresión 2 (entero)
`2 Expresión "2" (comando)
Write-Output 2 Expresión 2 (entero)
2+2 Expresión 4 (entero)
Write-Output 2+2 Argumento "2+2" (cadena)
Write-Output(2+2) Expresión 4 (entero)
$a Expresión 4 (entero)
Write-Output $a Expresión 4 (entero)
$a+2 Expresión 6 (entero)
Write-Output $a+2 Argumento "4+2" (cadena)
$- Argumento "$-" (comando)
Write-Output $- Argumento "$-" (cadena)
a$a Expresión "a$a" (comando)
Write-Output a$a Argumento "a4" (cadena)
a'$a' Expresión "a$a" (comando)
Write-Output a'$a' Argumento "a$a" (cadena)
a"$a" Expresión "a$a" (comando)
Write-Output a"$a" Argumento "a4" (cadena)
a$(2) Expresión "a$(2)" (comando)
Write-Output a$(2) Argumento "a2" (cadena)

Cada token se puede interpretar como algún tipo de objeto, como booleano o string. PowerShell intenta determinar el tipo de objeto de la expresión. El tipo de objeto depende del tipo de parámetro que espera un comando y de si PowerShell sabe cómo convertir el argumento al tipo correcto. En la tabla siguiente se muestran varios ejemplos de los tipos asignados a los valores devueltos por las expresiones.

Ejemplo Modo Resultado
Write-Output !1 argumento "!1" (cadena)
Write-Output (!1) expresión False (booleano)
Write-Output (2) expresión 2 (entero)
Set-Variable AB A,B argumento "A","B" (matriz)
CMD /CECHO A,B argumento 'A,B' (cadena de texto)
CMD /CECHO $AB expresión "A B" (matriz)
CMD /CECHO :$AB argumento ":A B" (cadena)

Pasar argumentos a comandos nativos

Al ejecutar comandos nativos desde PowerShell, PowerShell analiza primero los argumentos. A continuación, los argumentos analizados se combinan en una sola cadena con cada parámetro separado por un espacio.

Por ejemplo, el comando siguiente llama al programa icacls.exe.

icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Para ejecutar este comando en PowerShell 2.0, debe usar caracteres de escape para evitar que PowerShell malinterprete los paréntesis.

icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F

El símbolo de parada

A partir de PowerShell 3.0, puede usar el token de detención del análisis (--%) para impedir que PowerShell interprete la entrada como comandos o expresiones de PowerShell.

Nota:

El token de detención del análisis solo está diseñado para su uso en plataformas Windows.

Al llamar a un comando nativo, coloque el token de detención del análisis antes de los argumentos del programa. Esta técnica es mucho más fácil que usar caracteres de escape para evitar errores de interpretación.

Cuando encuentra un token de parada, PowerShell trata los caracteres restantes de la línea como un literal. La única interpretación que realiza es sustituir los valores de las variables de entorno que usan la notación estándar de Windows, como %USERPROFILE%.

icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F

PowerShell envía la siguiente cadena de comandos al programa icacls.exe:

X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

El token de detención de análisis solo es efectivo hasta la siguiente nueva línea o carácter de pipeline. No se puede utilizar un carácter de continuación (`) para ampliar su efecto ni utilizar un delimitador de comando (;) para finalizar su efecto.

Aparte de %variable% las referencias a variables de entorno, no se puede incrustar ningún otro elemento dinámico en el comando. No se admite el escape de un % carácter como %%, de la forma en que puede hacerlo dentro de los archivos por lotes. %<name>% se expanden invariablemente. Si <name> no hace referencia a una variable de entorno definida, el token se pasa a través de as-is.

No puede utilizar la redirección de secuencias (como >file.txt) porque se pasan literalmente como argumentos al comando de destino.

Pasar argumentos que contienen comillas

Algunos comandos nativos esperan argumentos que contienen caracteres de comillas. Normalmente, el análisis de la línea de comandos de PowerShell quita el carácter de comilla que proporcionó. A continuación, los argumentos analizados se combinan en una sola cadena con cada parámetro separado por un espacio. A continuación, esta cadena se asigna a la propiedad Arguments de un ProcessStartInfo objeto . Las comillas dentro de la cadena deben escaparse mediante comillas adicionales o caracteres de barra diagonal inversa (\).

Nota:

PowerShell no reconoce el carácter de barra diagonal inversa (\) como carácter de escape. Es el carácter de escape utilizado por la API subyacente para ProcessStartInfo.Arguments.

Para obtener más información sobre los requisitos de escape, consulte la documentación de ProcessStartInfo.Arguments.

Los siguientes ejemplos de uso de la TestExe.exe herramienta. Esta herramienta la usan las pruebas de Pester en el repositorio de origen de PowerShell. El objetivo de estos ejemplos es pasar la ruta "C:\Program Files (x86)\Microsoft\" de acceso del directorio a un comando nativo para que reciba la ruta de acceso como una cadena entre comillas.

El parámetro echoargs de TestExe muestra los valores recibidos como argumentos para el ejecutable. Puede usar esta herramienta para comprobar que ha escapado correctamente de los caracteres de los argumentos.

TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\\"""""
TestExe -echoargs """""C:\Program Files (x86)\Microsoft\\"""""
TestExe -echoargs "\""C:\Program Files (x86)\Microsoft\\"""
TestExe -echoargs --% "\"C:\Program Files (x86)\Microsoft\\"
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""

La salida es la misma para todos los ejemplos:

Arg 0 is <"C:\Program Files (x86)\Microsoft\">

Puede compilar TestExe desde el código fuente. Véase TestExe.

Pasar argumentos a comandos de PowerShell

A partir de PowerShell 3.0, puede usar el token "" de fin de parámetros "" (--) para impedir que PowerShell interprete la entrada como parámetros de PowerShell. Se trata de una convención especificada en la especificación de utilidades y shell de POSIX.

El token de fin de parámetros (--) indica que todos los argumentos siguientes deben pasarse en su forma real como si se colocaran comillas dobles alrededor de ellos. Por ejemplo, con -- puede generar la cadena -InputObject sin usar comillas ni interpretarla como parámetro:

Write-Output -- -InputObject
-InputObject

A diferencia del token de detención del análisis (--%), PowerShell puede interpretar los valores que siguen al token de -- como expresiones.

Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64

Este comportamiento solo se aplica a los comandos de PowerShell. Si usa el token de -- al llamar a un comando externo, la cadena -- se pasa como argumento a ese comando.

TestExe -echoargs -a -b -- -c

La salida muestra que -- se pasa como argumento a TestExe.

Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>

Consulte también