Compartir a través de


about_Parsing

Descripción breve

Describe cómo Analiza PowerShell los comandos.

Descripción larga

Al escribir un comando en el símbolo del sistema, PowerShell divide el texto del comando en una serie de segmentos denominados tokens y, a continuación, determina cómo interpretar cada token.

Por ejemplo, si escribe:

Write-Host book

PowerShell divide el comando en dos tokens y Write-Hostbook, 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 un 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 es posible que no ejecute el cmdlet previsto.
  • Get-Help y Get-Command no reconocen nombres sin verbos.

Modo de expresión

El modo de expresión está pensado 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
  • Los literales de cadena de caracteres deben estar entre comillas.
  • Los números se tratan como valores numéricos en lugar de como una serie de caracteres (a menos que se escapen).
  • Los operadores, incluidos los operadores unarios como - y -not los operadores binarios como + y , -gtse interpretan como operadores y aplican sus operaciones respectivas en sus argumentos (operandos).
  • Las expresiones de atributo y conversión se analizan como expresiones y se aplican a expresiones subordinadas, por ejemplo, [int] '7'.
  • Las referencias de variables se evalúan en sus valores, pero la expansión (es decir, pegar conjuntos de parámetros prerrellenados) está prohibida y produce un error del analizador.
  • Cualquier otra cosa se tratará como un comando que se va a invocar.

Modo de argumento

Al analizar, PowerShell primero busca interpretar la entrada como una expresión. Pero cuando se encuentra una invocación de comandos, 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:

  • 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 de variable puede incluir el acceso a miembros o la indexación.

    • 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 inicio de un nuevo argumento. Por ejemplo, da como resultado $HOME.Length-more dos argumentos: el valor de y el literal -morede $HOME.Length cadena .
  • Comillas (' y ") comienzan las cadenas

  • Llaves ({}) inician nuevos bloques de script

  • Comas (,) introduce listas pasadas como matrices, excepto cuando el comando al 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

  • El operador Subexpression ($()) comienza una expresión incrustada.

  • 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 principio de un token, se crea un nuevo contexto de análisis que puede contener expresiones o comandos anidados.

    • Cuando va seguido de caracteres adicionales, el primer carácter adicional se considera el inicio de un nuevo argumento independiente.
    • Cuando un literal $() sin comilla 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 metacharacters que todavía necesitan escape.

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

Ejemplos

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

Ejemplo Mode Resultado
2 Expression 2 (entero)
`2 Expression "2" (comando)
Write-Output 2 Expression 2 (entero)
2+2 Expression 4 (entero)
Write-Output 2+2 Argumento "2+2" (cadena)
Write-Output(2+2) Expression 4 (entero)
$a Expression 4 (entero)
Write-Output $a Expression 4 (entero)
$a+2 Expression 6 (entero)
Write-Output $a+2 Argumento "4+2" (cadena)
$- Argumento "$-" (comando)
Write-Output $- Argumento "$-" (cadena)
a$a Expression "a$a" (comando)
Write-Output a$a Argumento "a4" (cadena)
a'$a' Expression "a$a" (comando)
Write-Output a'$a' Argumento "a$a" (cadena)
a"$a" Expression "a$a" (comando)
Write-Output a"$a" Argumento "a4" (cadena)
a$(2) Expression "a$(2)" (comando)
Write-Output a$(2) Argumento "a2" (cadena)

Cada token se puede interpretar como algún tipo de objeto, como Boolean 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 Mode 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)
CMD /CECHO $AB expresión 'A B' (matriz)
CMD /CECHO :$AB Argumento ':A B' (cadena)

Paso de 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 siguiente comando llama al icacls.exe programa.

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

Token de detención del análisis

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

Nota

El token de detención del análisis solo está pensado 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 detención del análisis, PowerShell trata los caracteres restantes de la línea como 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 comando al icacls.exe programa:

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

El token de detención del análisis solo es efectivo hasta el siguiente carácter de nueva línea o canalización. No puede usar un carácter de continuación (`) para extender su efecto o usar un delimitador de comandos (;) para finalizar su efecto.

Aparte de %variable% las referencias de variables de entorno, no se pueden insertar otros elementos dinámicos en el comando . No se admite el escape de un % carácter como %%, la forma en que se puede realizar dentro de los archivos por lotes. %<name>% los tokens se expanden invariablemente. Si <name> no hace referencia a una variable de entorno definida, el token se pasa tal cual.

No puede usar el redireccionamiento de secuencias (como >file.txt) porque se pasan textualmente como argumentos al comando de destino.

Pasar argumentos que contienen caracteres de 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 con 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 que usa la API subyacente para ProcessStartInfo.Arguments.

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

En los ejemplos siguientes se usa la TestExe.exe herramienta . Esta herramienta la usan las pruebas 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 a partir del código fuente. Consulte 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 que siguen 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 (--%), powerShell puede interpretar los valores siguientes al -- token como expresiones.

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

Este comportamiento solo se aplica a los comandos de PowerShell. Si usa el -- token 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