2016-03-15 3 views
-2

У меня есть два сценария PowerShell. Первый сценарий имеет следующий код:Передача переменной другому скрипту

$var = "abc"  
$DIR = "C:\" 
$SCRIPT_NAME = "abc.ps1" 
&"${DIR}\${SCRIPT_NAME}" #execute the second script 

Если я хочу передать переменную $var ко второму сценарию, как я достичь этого? Какой код мне нужен для ввода первого и второго скриптов?

ответ

2

Параметры (рекомендуется): Используйте параметры для передачи значений второму сценарию.

Step2.ps1:

param ($myparameter) 

write-host $myparameter 

Step1.ps1:

$var = "abc"  
$DIR = "C:\" 
$SCRIPT_NAME = "step2.ps1" 
&"${DIR}\${SCRIPT_NAME}" -myparameter $var 

Альтернативные: Вы также могли бы использовать аргументы $args (дополнительные значения не связаны с параметром). Вы можете указать первый аргумент, используя $args[0]. Я бы, однако всегда рекомендуем параметры в качестве аргументов должен быть в определенном порядке (если несколько аргументов) и т.д.

Step2.ps1:

write-host $args[0] 

Step1.ps1:

$var = "abc"  
$DIR = "C:\" 
$SCRIPT_NAME = "step2.ps1" 
&"${DIR}\${SCRIPT_NAME}" $var 
+0

$ var1 = "ABC" $ var2 = "EFG" $ DIR = "C:" $ SCRIPT_NAME = "2.ps1" & "$ {DIR} \ $ {SCRIPT_NAME } "$ var1 $ var2 $ test1 = $ args [0] $ test2 = $ args [1] Выше код не работает. Как передать несколько переменных? Благодарю. – tset

+0

@tset «Не работает» является недостаточным описанием проблемы. Какой результат вы ожидали, и как это отличается от полученного вами результата? –

1

Существует несколько способов сделать то, что вы хотите, два из которых уже были предложены @FrodeF..

  • Pass переменную в качестве имени() параметра:

    # script1.ps1 
    $var = 'foo' 
    $dir = 'C:\some\folder' 
    $scriptname = "script2.ps1" 
    & "${dir}\${scriptname}" -Foo $var 
    
    # script2.ps1 
    Param($foo) 
    Write-Output $foo 
    

    Это чистое решение. У вас есть четко определенный интерфейс и передайте переменную четким способом из одного сценария в другой.

    Определения параметров также позволят вам сделать параметр обязательным (чтобы скрипт попросил пользователя предоставить ввод, если параметр был опущен), требуется конкретный тип данных, легко включить validation routines или добавить comment-based help.

    # script2.ps1 
    <# 
    .SYNOPSIS 
    Short description of the script or function. 
    
    .DESCRIPTION 
    Longer description of what the script or function actually does. 
    
    .PARAMETER Foo 
    Description of the parameter Foo. 
    #> 
    [CmdletBinding()] 
    Param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] 
        [ValidateRange(2,42)] 
        [int]$foo 
    ) 
    Write-Output $foo 
    

    См. Get-Help about_Function_Advanced_Parameters для получения дополнительной информации.

  • передать переменную в качестве безымянного аргумента:

    # script1.ps1 
    $var = 'foo' 
    $dir = 'C:\some\folder' 
    $scriptname = "script2.ps1" 
    & "${dir}\${scriptname}" $var 
    
    # script2.ps1 
    Write-Output $args[0] 
    

    Это второй лучший подход, потому что вы все-таки передать переменную в четком пути, но интерфейс не так как и раньше.

  • Определить переменную в качестве переменной среды:

    # script1.ps1 
    $env:var = 'foo' 
    $dir = 'C:\some\folder' 
    $scriptname = "script2.ps1" 
    & "${dir}\${scriptname}" 
    
    # script2.ps1 
    Write-Output $env:var 
    

    Это менее чистый подход, чем те, аргументов на основе, так как переменная передается с помощью «бокового канала» (далее технологическая среда, которая унаследована дочерними процессами).

  • Просто определить переменную в первом сценарии и использовать его во втором:

    # script1.ps1 
    $var = 'foo' 
    $dir = 'C:\some\folder' 
    $scriptname = "script2.ps1" 
    & "${dir}\${scriptname}" 
    
    # script2.ps1 
    Write-Output $var 
    

    Это будет работать, как хорошо, потому что с помощью call operator (&) второй скрипт запускается в том же контексте, что и первый скрипт, и, таким образом, имеет доступ к тем же переменным. Тем не менее, «прохождение» такой переменной легко сломается, если кто-то запускает второй скрипт в другом контексте/области или поддерживает его, не зная о неявной зависимости.

    Если вы хотите пройти этот маршрут, обычно лучше использовать первый скрипт только для определения переменных (и функций), а dot-source - во втором скрипте, так что определения импортируются в scope второго скрипта:

    # script1.ps1 
    $var = 'foo' 
    
    # script2.ps1 
    . 'C:\path\to\script1.ps1' 
    Write-Output $var 
    
  • Технически передача значений через файл будет другой вариант. Тем не менее, я бы рекомендовал не использовать этот подход по нескольким причинам:

    • это склонное к ошибкам из-за неправильное разрешение (может быть уменьшено путем создания файла в папке $env:TEMP),
    • это склонное к засорению файловой системы если вы не очистите файл после этого,
    • он без необходимости генерирует дисковый ввод-вывод, когда достаточно простых операций в оперативной памяти, предоставляемых языком.