Como passar parâmetros para uma função?

10

Eu preciso processar uma cópia de trabalho do SVN em um script PS, mas tenho dificuldade em transmitir argumentos para as funções. Aqui está o que eu tenho:

function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $($args[0])"
echo "1: $($args[1])"
$items = get-childitem $args[1] 
$items | foreach-object -process {foo $args[0] $_}

Eu quero passar $arg[0] como $arg1 para foo e $arg[1] as $arg2 . No entanto, isso não funciona, por algum motivo $arg1 está sempre vazio:

PS C:\Users\sbi> .\test.ps1 blah .\Dropbox
0: blah
1: .\Dropbox
C:\Users\sbi\Dropbox\Photos
C:\Users\sbi\Dropbox\Public
C:\Users\sbi\Dropbox\sbi
PS C:\Users\sbi>

Observação: O parâmetro "blah" não é passado como $arg1 .

Tenho certeza absoluta de que é algo hilário e simples (eu só comecei a fazer PS e ainda me sinto muito desajeitado), mas eu bati com isso por mais de uma hora e não consigo encontrar nada.

    
por sbi 06.07.2012 / 20:57

3 respostas

1

A matriz $arg[] parece perder o escopo dentro do ForEach-Object .

function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $($args[0])"
echo "1: $($args[1])"
$zero = $args[0]
$one = $args[1]
$items = get-childitem $args[1] 
$items | foreach-object {
    echo "inner 0: $($zero)"
    echo "inner 1: $($one)"
}
    
por 06.07.2012 / 21:26
10

A razão pela qual $ args [0] não está retornando nada no objeto foreach é que $ args é uma variável automática que usa parâmetros não nomeados e sem correspondência em um comando e o foreach-object é um novo comando. Não há nenhum parâmetro não correspondido para o bloco de processo, então $ args [0] é nulo.

Uma coisa que pode ajudar é que seus scripts podem ter parâmetros, assim como funções.

param ($SomeText, $SomePath)
function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $SomeText"
echo "1: $SomePath"
$items = get-childitem $SomePath
$items | foreach-object -process {foo $SomeText $_}

À medida que começar a querer mais funcionalidade com seus parâmetros, convém conferir uma postagem no Eu escrevi sobre a progressão de parâmetros de $ args para os parâmetros avançados atuais que podemos usar agora.

    
por 06.07.2012 / 21:26
3

Tente algo assim:

# Use an advanced function
function foo
{
  [CmdletBinding()]
  param (
      [string] $arg1
    , [string] $arg2
  )

  Write-Host -Object $arg1;
  Write-Host -Object $arg2;
}

# Create array of "args" to emulate passing them in from command line.
$args = @('blah', 'c:\test');

echo "0: $($args[0])"
echo "1: $($args[1])"

# Force items to be returned as an array, in case there's only 1 item returned
$items = @(Get-ChildItem -Path $args[1]);
Write-Host -Object "There are $($items.Count) in '$items";

# Iterate over items found in directory
foreach ($item in $items) {
    foo -Arg1 $args[0] -Arg2 $item.FullName
}
    
por 06.07.2012 / 21:24

Tags