
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 $input
una 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 $input
el 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-Host
acepta 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 $input
funcionamiento 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-object
bucle 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-Output
có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.ps1
secuencia 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
Pero no entiendo lo que significa ser enumerador.
Además, según$input
declaració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 $input
en 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
$input
variable está disponible sólo para funciones y bloques de script (que son funciones sin nombre).
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 $input
para 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 $input
que 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
.
(operador fuente o punto)- Para cada objeto
EstándarAliaspara Foreach-Object: el
%
símbolo '', ForEach - Para cada método