使用脚本中的参数调用第二个脚本

     2023-02-25     200

关键词:

【中文标题】使用脚本中的参数调用第二个脚本【英文标题】:Invoke a second script with arguments from a script 【发布时间】:2012-10-02 18:18:12 【问题描述】:

我有一个脚本,它读取一个配置文件,该文件生成一组名称值对,我想将它们作为参数传递给第二个 PowerShell 脚本中的函数。

我不知道在设计时会在这个配置文件中放置什么参数,所以在我需要调用第二个 PowerShell 脚本的时候,我基本上只有一个变量,它具有第二个脚本的路径,第二个变量是一个参数数组,传递给路径变量中标识的脚本。

因此,包含第二个脚本 ($scriptPath) 路径的变量可能具有如下值:

"c:\the\path\to\the\second\script.ps1"

包含参数的变量 ($argumentList) 可能类似于:

-ConfigFilename "doohickey.txt" -RootDirectory "c:\some\kind\of\path" -Max 11

如何使用 $argumentList 中的所有参数执行 script.ps1?

我希望第二个脚本中的任何写入主机命令对调用第一个脚本的控制台可见。

我尝试过点源、Invoke-Command、Invoke-Expression 和 Start-Job,但我没有找到不会产生错误的方法。

例如,我认为最简单的第一条路线是尝试如下调用的 Start-Job:

Start-Job -FilePath $scriptPath -ArgumentList $argumentList

...但是失败并出现以下错误:

System.Management.Automation.ValidationMetadataException:
Attribute cannot be added because it would cause the variable
ConfigFilename with value -ConfigFilename to become invalid.

...在这种情况下,“ConfigFilename”是第二个脚本定义的参数列表中的第一个参数,我的调用显然试图将其值设置为“-ConfigFilename”,这显然是为了识别按名称参数,而不是设置其值。

我错过了什么?

编辑:

好的,这是一个被调用脚本的模型,在一个名为 invokee.ps1 的文件中

Param(
[parameter(Mandatory=$true)]
[alias("rc")]
[string]
[ValidateScript( Test-Path $_ -PathType Leaf )]
$ConfigurationFilename,
[alias("e")]
[switch]
$Evaluate,
[array]
[Parameter(ValueFromRemainingArguments=$true)]
$remaining)

function sayHelloWorld()

    Write-Host "Hello, everybody, the config file is <$ConfigurationFilename>."
    if ($ExitOnErrors)
    
        Write-Host "I should mention that I was told to evaluate things."
    
    Write-Host "I currently live here: $gScriptDirectory"
    Write-Host "My remaining arguments are: $remaining"
    Set-Content .\hello.world.txt "It worked"


$gScriptPath = $MyInvocation.MyCommand.Path
$gScriptDirectory = (Split-Path $gScriptPath -Parent)
sayHelloWorld

...这里是调用脚本的模型,在一个名为 invoker.ps1 的文件中:

function pokeTheInvokee()

    $scriptPath = (Join-Path -Path "." -ChildPath "invokee.ps1")
    $scriptPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($scriptPath)
    
    $configPath = (Join-Path -Path "." -ChildPath "invoker.ps1")
    $configPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($configPath)
    
    $argumentList = @()
    $argumentList += ("-ConfigurationFilename", "`"$configPath`"")
    $argumentList += , "-Evaluate"

    Write-Host "Attempting to invoke-expression with: `"$scriptPath`" $argumentList"
    Invoke-Expression "`"$scriptPath`" $argumentList"
    Invoke-Expression ".\invokee.ps1 -ConfigurationFilename `".\invoker.ps1`" -Evaluate
    Write-Host "Invokee invoked."


pokeTheInvokee

当我运行invoker.ps1 时,这是我在第一次调用Invoke-Expression 时遇到的错误:

Invoke-Expression : You must provide a value expression on
the right-hand side of the '-' operator.

第二个调用工作得很好,但一个显着的区别是第一个版本使用的参数的路径中有空格,而第二个没有。我是否错误地处理了这些路径中存在的空格?

【问题讨论】:

如果您为每个脚本提供源代码也会有所帮助。例如,创建 POC(概念证明)项目来说明您的问题。然后我们可以测试并使用它,也许有人会找到解决方案或解决方法。 是的 - 我正在尝试制作一个迷你版来说明。很快就会发布... 【参考方案1】:

啊哈。原来这是一个简单的问题,脚本路径中有空格。

将 Invoke-Expression 行更改为:

Invoke-Expression "& `"$scriptPath`" $argumentList"

...足以让它开始。感谢 Neolisk 的帮助和反馈!

【讨论】:

添加到您的答案中。路径中有空格意味着您必须使用引号。 Invoke-Expression 将引号视为字符串,而不是命令。因此,如果要执行字符串,则需要使用“调用运算符”,即示例开头的 & 符号。 Here 是呼叫操作员的定义。 当我以这种方式尝试我的脚本时,它有一个缺少结束引号的语法错误。下面的方法 2 对我有用 我的脚本参数列表中的一个字符串参数中的分号字符有问题。 Invoke-Expression 一直将其解释为语句分隔符,并且仅将字符串的开头作为参数传递给脚本。当我在我的代码中应用这个答案时,它工作得很好。【参考方案2】:

Invoke-Expression 应该可以正常工作,只要确保您正确使用它即可。对于您的情况,它应该如下所示:

Invoke-Expression "$scriptPath $argumentList"

我使用 Get-Service 测试了这种方法,并且似乎按预期工作。

【讨论】:

Invoke-Expression "$scriptPath $argumentList" 立即返回并且似乎没有运行脚本。如果我将其更改为 Invoke-Expression "powershell $scriptPath $argumentList",PowerGui 似乎会挂起。 @Hoobajoob:Invoke-Expression 不会立即返回,它会耐心等待调用的脚本结束——我刚刚在 POC 项目上进行了测试。您定位的脚本一定有问题。 Hm - 我已经从批处理文件、Visual Studio IDE、DOS 命令行和 powershell 控制台会话中以多种不同的方式运行第二个脚本,但这是我第一次尝试运行它来自另一个powershell脚本。脚本本身可能有哪些内容会阻止它通过 Invoke-Expression 成功启动? 这只有在参数列表中的对象都是字符串类型时才有效,对吧? @Backwards_Dave: $scriptPath$argumentList 这里是字符串。一个字符串可以包含一个非字符串参数(写成一个字符串)。希望它能回答你的问题。【参考方案3】:

其实很多simpler:

方法一:

Invoke-Expression $scriptPath $argumentList

方法二:

& $scriptPath $argumentList

方法三:

$scriptPath $argumentList

如果您的scriptPath 中有空格,请不要忘记将它们转义`"$scriptPath`"

【讨论】:

感谢您的选择,我真的很喜欢这个答案在另一个问题上提供的附加选项。 ***.com/a/33206405/3794873【参考方案4】:

这是一个涵盖从 PS 脚本调用另一个 PS 脚本的更一般性问题的答案,如果您正在编写由许多小型、用途狭窄的脚本组成的脚本,您可能会这样做。

我发现这只是使用点源的一个案例。也就是说,您只需这样做:

# This is Script-A.ps1

. ./Script-B.ps1 -SomeObject $variableFromScriptA -SomeOtherParam 1234;

我发现所有的 Q/A 都非常混乱和复杂,最终找到了上面的简单方法,这真的就像调用另一个脚本一样,好像它是原始脚本中的一个函数,我觉得这更直观。

点源可以“导入”整个其他脚本,使用:

. ./Script-B.ps1

现在好像两个文件合并了。

最终,我真正缺少的是我应该构建一个可重用函数模块的概念。

【讨论】:

&amp; "./Script-B.ps1" -SomeObject $variableFromScriptA -SomeOtherParam 1234 一个模块不需要导出到其他系统有什么好处?【参考方案5】:

我们可以为此使用splatting:

& $command @args

@args (automatic variable $args) 被放入参数数组中。

在 PS 下,5.1

【讨论】:

【参考方案6】:

我尝试了使用 Invoke-Expression cmdlet 的公认解决方案,但它对我不起作用,因为我的参数上有空格。我试图解析参数并转义空格,但我无法使其正常工作,而且在我看来这确实是一项肮脏的工作。 所以经过一些实验,我对这个问题的看法是:

function Invoke-Script

    param
    (
        [Parameter(Mandatory = $true)]
        [string]
        $Script,

        [Parameter(Mandatory = $false)]
        [object[]]
        $ArgumentList
    )

    $ScriptBlock = [Scriptblock]::Create((Get-Content $Script -Raw))
    Invoke-Command -NoNewScope -ArgumentList $ArgumentList -ScriptBlock $ScriptBlock -Verbose


# example usage
Invoke-Script $scriptPath $argumentList

此解决方案的唯一缺点是您需要确保您的脚本没有“Script”或“ArgumentList”参数。

【讨论】:

【参考方案7】:

您可以像 SQL 查询一样执行它。 首先,构建您的命令/表达式并存储在变量中并执行/调用。

$command =  ".\yourExternalScriptFile.ps1" + " -param1 '$paramValue'"

它非常前卫,我认为不需要解释。 所以现在都准备好执行你的命令了,

Invoke-Expression $command

我建议在这里捕获异常

【讨论】:

【参考方案8】:

我假设您想从另一个 .ps1 文件运行 .ps1 文件 [此处为 $scriptPath 以及存储在 $argumentList 中的多个参数]

Invoke-Expression "& $scriptPath $argumentList"

这段代码可以正常工作

【讨论】:

将第二个参数从 shell 脚本传递到 Java [重复]

】将第二个参数从shell脚本传递到Java[重复]【英文标题】:PassingsecondargumentonwardsfromashellscripttoJava[duplicate]【发布时间】:2011-04-2901:07:30【问题描述】:如果我将任意数量的参数传递给在内部调用Java程序的shell脚本,我如何才能将... 查看详情

为啥“使用严格”导致函数未定义

】为啥“使用严格”导致函数未定义【英文标题】:Whyis\'UseStrict\'causingfunctionstobeundefined为什么“使用严格”导致函数未定义【发布时间】:2015-07-1016:35:13【问题描述】:我有一个正在加载两个脚本的部分。第二个脚本调用第一... 查看详情

我可以从另一个 shell 脚本调用一个 shell 脚本的函数吗?

...hfunc1func2first.sh将调用带有一些参数的第二个shell脚本和将使用特定于该函数的一些其他参数调用fu 查看详情

第二个参数是获取shell脚本函数中第一个参数的内容[重复]

】第二个参数是获取shell脚本函数中第一个参数的内容[重复]【英文标题】:Secondparameterisgettingthecontentofthefirstparameterinshellscriptfunction[duplicate]【发布时间】:2020-10-2312:42:15【问题描述】:我在shell脚本中创建一个函数,我需要传... 查看详情

从 Unity 中的其他脚本调用函数

...【发布时间】:2016-10-2320:17:49【问题描述】:我正在尝试使用附加到第二个游戏对象的其他脚本从附加到游戏对象的脚本中调用函数。这两个游戏对象被称为:Player、GameManager。玩家有一个名为Gold的脚本,而游戏管理器有一个名... 查看详情

shell 脚本中的命令行参数

...个参数的命令是什么?【问题讨论】:【参考方案1】:使用shift:#!/usr 查看详情

当第一个脚本运行第二个脚本方法时,第二个脚本无法识别第一个脚本的变量

】当第一个脚本运行第二个脚本方法时,第二个脚本无法识别第一个脚本的变量【英文标题】:Secondscriptdoesnotrecognizevariablesoffirstscriptwhenfirstscriptrunssecondscriptmethod【发布时间】:2021-01-1523:33:52【问题描述】:我有这个脚本MainGUI.p... 查看详情

如何使用标题中的两个参数和正文中的第二个参数从另一个 MVC 项目调用 Web API

】如何使用标题中的两个参数和正文中的第二个参数从另一个MVC项目调用WebAPI【英文标题】:HowtoCallWebAPIfromAnotherMVCProjectwithtwoParameteroneinheaderandsecondinbody【发布时间】:2021-12-3121:09:44【问题描述】:我想从mvc项目中调用api操作,... 查看详情

在第二个脚本函数中传递来自第一个 python 脚本主函数的数据

...0-05-0604:39:57【问题描述】:我需要在第二个脚本的函数中使用第一个脚本中的一些数据,但不确定在我的情况下如何正确执行此操作。我希望有一个简单的答案,但不幸的是,我被困在了这个问题上。第 查看详情

shell脚本内调用另外一个shell脚本的几种方法(代码片段)

...ameter_usage.sh中的变量和函数在test_call_other_shell.sh中可直接使用   2.通过/bin/bash:运行在不同的进程   3.通过sh:运行在不同的进程   4.通过.:运行在相同的进程,在test_call_other_shell.sh中调用parameter_usage.sh后,parameter_usage.s... 查看详情

脚本不适用于引用组件的第二个实例

】脚本不适用于引用组件的第二个实例【英文标题】:Scriptnotworkingforsecondinstanceofreferencedcomponent【发布时间】:2012-09-2822:22:12【问题描述】:我有一个脚本用来旋转无序列表(LI)中的图像。如果页面上只有一个引用类的实例,则... 查看详情

执行位于另一个文件夹中的 PHP 文件

...位于新文件夹中的第二个脚本。但是我需要第二个脚本来使用它的路径,而不是它被调用/执行的路径。(上传脚本)这就是我尝试从上传脚本执行脚本 查看详情

在shell脚本中将变量的值作为命令行参数传给程序

编写一个脚本,在其中调用一个函数,把一个变量的值作为参数传递给该函数?坐等回答谢谢!fun()echo"$1"fun"abc"$1就代表了你传进去的第一个参数,$2当然就是第二个参数,fun就是你定义的函数名,后面的“abc”就... 查看详情

使用 QPushbutton 将变量传递到第二个脚本并执行它

】使用QPushbutton将变量传递到第二个脚本并执行它【英文标题】:UsingQPushbuttontopassvariablesintoasecondscriptandexecuteit【发布时间】:2021-08-2519:02:14【问题描述】:我正在尝试使用PyQt5gui的输入值来运行第二个python脚本。我正在猜测的... 查看详情

jenkins参数化构建过程中的各个参数之间是没有关联的吗

...job本次运行参数通过冲命名参数名,将数值传递给下游job使用;至于你所说下游job参数化构建过程是否能调用成功,就要看jenkins是否支持你的构建脚本运行工具,经测试传递的参数在ftp命令行是不能读取的;据此可以推论,此pl... 查看详情

shell脚本中的$#表示啥意思呢?

...shell文件接受的第一个参数、第二个参数的意思吧?shell脚本执行过程中把第一个字符串作为脚本名称(或程序名称)处理,第二、第三。。。都作为参数处理。shell会将这些参数默认的赋给变量123。。。所以当你echo$1$2的时候看... 查看详情

如果需要第一个函数,如何在脚本中执行第二个函数?

】如果需要第一个函数,如何在脚本中执行第二个函数?【英文标题】:Howdoyouexecutethesecondfunctioninascriptifitneedsthefirstfunction?【发布时间】:2017-07-2018:19:42【问题描述】:我认为这是基本的,我已经看到了我所问问题的多个版本... 查看详情

如何使用 shell/perl 脚本获取一个月的第二个星期六? [关闭]

】如何使用shell/perl脚本获取一个月的第二个星期六?[关闭]【英文标题】:Howtogetsecondsaturdayofamonthusingshell/perlscript?[closed]【发布时间】:2016-07-0608:51:18【问题描述】:请提供脚本代码以找出一个月内的第二个星期六【问题讨论】... 查看详情