Recurso de apoyo

Recurso de apoyo

Supongamos que tengo un simple test.ps1:

Write-Host "access input for the 1st time: $input"
Write-Host "access input for the 2nd time: $input"

Entonces lo hago'foo' | .\test.ps1

Salida:

acceder a la entrada por primera vez: foo
acceder a la entrada por segunda vez:

Después de acceder $inputuna vez, el valor desaparece. ¿Por qué?

El documentodice que es porque $input es un enumerador:

Dado que $input es un enumerador, acceder a cualquiera de sus propiedades hace que $input ya no esté disponible. Puede almacenar $input en otra variable para reutilizar las propiedades de $input.

Pero no entiendo lo que significa ser enumerador.

Hasta donde yo sé, si incluyo una lista de cosas, la lista no se enumerará porque no tengo un process{}bloque. Por ejemplo, si lo hago @(1,2,3) | .\test.ps1, mi código se ejecutará solo una vez y la matriz se tratará como un solo objeto.

acceder a la entrada por primera vez: 1 2 3
acceder a la entrada por segunda vez:

Entonces no entiendo qué se enumera y por qué $input es un enumerador.

Respuesta1

Debes considerar el resto de lo que hay en esa descripción y tal vez comprobarlo.about_Functions_Advancedyabout_Funciones_Métodos_avanzados.

Tu ejemplo simplemente no tiene mucho sentido. Llamar al script funciona como una función anónima. Como solo le dejas usar $inputel primer caso es lo que sucede:

En una función sin un bloque de inicio, proceso o finalización, la variable $input enumera la colección de todas las entradas de la función.

Write-Hostacepta la enumeración y la itera. Por lo tanto, aparentemente solo obtienes un valor único. Básicamente, está llamando a ".toString()".

Usando un bucle encontrará que obtiene valores individuales.

$counter = 0;
$input | ForEach-Object {
    Write-Host "access input for the $counter time: $_"
    $counter = $counter + 1
}

Si necesita esta funcionalidad, probablemente sería mejor utilizar un bloque de proceso. Consulte la ayuda de la función avanzada para obtener más información sobre lo que eso significa.

begin {
    $counter = 0
}
process {
    Write-Host "access input for the $counter time: $_"
    $counter = $counter + 1
}

Ten en cuenta que en ese caso la forma de $inputfuncionamiento cambia ligeramente.

Según elinformación sobre enumeradorestener parámetros de función regulares con una definición adecuada suele ser preferible trabajar directamente con $input.

Respuesta2

Iterar sobre una 'lista de cosas' canalizando ellistaa unforeach-objectbucle con la llamada de script/función dentro de su archivo scriptblock.

Dentro de eso scriptblock, canalice el valor iterado a la llamada de función comoaportepara obtener el valor esperado por su valor de salida devuelto por llamada.

Esta solución PowerShell tiene la lógica del script envuelta en unfunción sencillabloque de instrucciones y no es necesario repetir el Write-Outputcódigo más de una vez: estándar, fácil y básico.

Por lo tanto, no hay necesidad de preocuparse especialmente con respecto al process{}bloque.

Test.ps1secuencia de comandos de PowerShell

Function Test {
    Write-Output "Access to your mom's: $input"
    };

Potencia Shellfuente de puntosguión y llámalo

. "$Env:USERPROFILE\Desktop\test.ps1"
@("car","house","bank account") | % { $_ | test  }

Producción

Access to your mom's: car
Access to your mom's: house
Access to your mom's: bank account

Desglose de la lógica

ingrese la descripción de la imagen aquí

Pero no entiendo lo que significa ser enumerador.

Además, según$inputdeclaraciónreferenciado y citado a continuación, esto significa que será el marcador de posición para el valor de entrada pasado como entrada, de modo que enumere ese valor pasado. Se utiliza $inputen el script y contiene el valor que recibió como entrada. El problema que tenía es que todos los valores se pasaron como una cadena larga concatenada según esos métodos.

  • Contiene un enumerador que enumera todas las entradas que se pasan a una función. La $inputvariable está disponible sólo para funciones y bloques de script (que son funciones sin nombre).

    Fuente

También, esa otra afirmación que no entendiste es solo decir[ $input] mantiene ese valor sólo en el caso en que se llama. No puede usarlo $inputpara obtener ningún valor antes o después de la llamada, solo se establece en un valor como entrada en la llamada.

Por último, puede establecer una variable en una llamada de funciónpara darle el resultado que $input"enumeró" en la llamada (es decir $var = "jewelry box" | test). Esto significa que la variable está disponible fuera de la llamada posteriormente con el valor $inputque tenía cuando se ejecutó.

Otras posibles soluciones de bonificación

## Input piped to script function call
@("car","house","bank account").ForEach( {$_ | test} );

## Uses "$_" as the placeholder to contain the value iterated right to the command no script or function needed
@("car","house","bank account").ForEach( { Write-Output "Access to your mom's: $_" } );

Recurso de apoyo

información relacionada