![](/img/trans.png)
[英]How do I create an application that runs in the background and is interactive in Linux?
[英]How do I create function that runs a command?
因此,我想做的是重新创建一个与Bash中使用的类似功能,但在Powershell中:
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "FAILED: $*"; }
我目前最感兴趣的部分是try()函数。 从本质上讲,它的作用是让我使用此功能包装命令并让其管理退出代码。 效果是这样的:
try doSomething -args
如果doSomething
以非零值退出,则它将命令输出到stderr并停止执行脚本。
我意识到Powershell有一个错误操作,可用于中止脚本,但似乎仅适用于Commandlet。 我需要可以在整个脚本中使用的任何东西。 我还希望避免大量冗长的try / catch逻辑使脚本混乱,因此希望获得诸如try / yell / die之类的优雅内容。 这样,我可以单独在此函数中编写处理,然后仅使用它来调用要处理的任何内容。
我找到了$MyInvocation
并认为这可能是其中的一种方法,但是我似乎找不到在函数中实际执行它的方法。 例如:
function run() {
$MyInvocation # ?? what do??
}
run doSomething -args
我想我可以自己解决其余问题,我只是不太了解如何编写此包装函数。 有任何想法吗?
因此,我做了一些俗气的事情,然后我对该命令进行了Invoke-Expression
并对剩下的内容进行了Invoke-Expression
,它似乎可以正常工作。 感觉超级hacky,所以我仍然可以接受一些想法:
function attempt() {
$thisCommand = $MyInvocation.Line.Trim()
Write-Output $thisCommand
Invoke-Expression $thisCommand.Substring(8)
if($LASTEXITCODE -ne 0) {
throw "Command failed $thisCommand"
exit 111
}
}
attempt doSomething -args
如果您希望函数运行任意命令并在该命令失败时抛出错误,则可以执行以下操作:
function Test-Command {
try {
$cmd, $params = $args
$params = @($params)
$global:LastExitCode = 0
$output = & $cmd @params 2>&1
if ($global:LastExitCode -ne 0) {
throw $output
}
$output
} catch {
throw $_
}
}
分解:
$cmd, $params = $args
获取自动变量 $args
(传递给函数的参数数组),并将其第一个元素分配给变量$cmd
,其余分配给变量$params
。
$params = @($params)
确保$params
包含一个数组(下一步需要),即使变量为空或仅具有单个值也是如此。
& $cmd @params
在展开参数时使用调用运算符 &
调用命令。 不要使用Invoke-Expression
。
重定向运算符 2>&1
将错误输出与常规输出合并,以便将两个输出流都捕获到变量$output
。
如果$cmd
是PowerShell cmdlet,则错误将引发异常,该异常由try
语句捕获。 然后将跳过try
块中的其余代码。 但是请注意,并非PowerShell cmdlet引发的所有错误都会自动终止错误(例如,请参见Scripting Guy博客上的“ PowerShell中的错误处理简介” )。 要将非终止错误转换为终止错误,您需要设置$ErrorActionPreference = 'Stop'
(完成后将其重置为原始值)。
如果$cmd
是外部命令,则错误不会引发异常,但是自动变量$LastExitCode
会使用命令的退出代码进行更新。 返回非零退出代码的命令将触发if
条件,并使用命令输出作为异常消息来引发自定义异常。 然后,该异常也会被try
语句捕获。 try
块中的其余代码再次被跳过。
$global:LastExitCode = 0
$LastExitCode
在每次运行前重置变量$LastExitCode
。 这是必需的,因为只有外部命令会返回退出代码,而PowerShell cmdlet不会。 由于$LastExitCode
保留了当前会话中上次运行的外部命令的退出代码,因此不重置变量将使在执行外部命令后运行的PowerShell cmdlet的状态检测$LastExitCode
。
仅在命令既不引发异常也不返回非零退出代码的情况下,才到达try
块的最后一行,该行回显捕获的命令输出。
任何捕获的异常都在catch
块中处理,该块仅将异常传递给函数的调用者。 当然,除了抛出错误,您还可以输出错误并退出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.