English 中文(简体)
Execute process conditionally in Windows PowerShell (e.g. the && and || operators in Bash)
原标题:

I m wondering if anybody knows of a way to conditionally execute a program depending on the exit success/failure of the previous program. Is there any way for me to execute a program2 immediately after program1 if program1 exits successfully without testing the LASTEXITCODE variable? I tried the -band and -and operators to no avail, though I had a feeling they wouldn t work anyway, and the best substitute is a combination of a semicolon and an if statement. I mean, when it comes to building a package somewhat automatically from source on Linux, the && operator can t be beaten:

# Configure a package, compile it and install it
./configure && make && sudo make install

PowerShell would require me to do the following, assuming I could actually use the same build system in PowerShell:

# Configure a package, compile it and install it
.configure ; if ($LASTEXITCODE -eq 0) { make ; if ($LASTEXITCODE -eq 0) { sudo make install } }

Sure, I could use multiple lines, save it in a file and execute the script, but the idea is for it to be concise (save keystrokes). Perhaps it s just a difference between PowerShell and Bash (and even the built-in Windows command prompt which supports the && operator) I ll need to adjust to, but if there s a cleaner way to do it, I d love to know.

最佳回答

You could create a function to do this, but there is not a direct way to do it that I know of.

function run-conditionally($commands) {
   $ranAll = $false
   foreach($command in $commands) {
      invoke-command $command
      if ($LASTEXITCODE -ne 0) {
          $ranAll = $false
          break; 
      }
      $ranAll = $true
   }

   Write-Host "Finished: $ranAll"

   return $ranAll
}

Then call it similar to

run-conditionally(@(".configure","make","sudo make install"))

There are probably a few errors there this is off the cuff without a powershell environment handy.

问题回答

I was really hurting for the lack of &&, too, so wrote the following simple script based on GrayWizardX s answer (which doesn t work as-is):

foreach( $command in $args )
{
  $error.clear()
  invoke-command $command
  if ($error) { break; }
}

If you save it as rc.ps1 (for "run conditionally") in a directory in your path, you can use it like:

rc {.configure} {make} {make install}

Using script blocks (the curly braces) as arguments instead of strings means you can use tab completion while typing out the commands, which is much nicer. This script is almost as good as &&, and works.





相关问题
Mutually exclusive powershell parameters

SCENARIO I m writing a cmdlet for Powershell 2.0 using Visual Studio 2008 and .NET 3.5 the cmdlet requires 3 arguments. my intended grammar of the cmdlet is something like this: cmdletname [foo|...

Run a program from PowerShell with timeout

I ll write a script that runs a program and wait for it finished. But if the program is not finished within a specified time I want that the program is killed.

How to transpose data in powershell

I have a file that looks like this: a,1 b,2 c,3 a,4 b,5 c,6 (...repeat 1,000s of lines) How can I transpose it into this? a,b,c 1,2,3 4,5,6 Thanks

Powershell v2 remoting and delegation

I have installed Powershell V2 on 2 machines and run Enable-PsRemoting on both of them. Both machines are Win 2003 R2 and are joined to the same active directory domain and I can successfully run ...

PowerShell -match operator and multiple groups

I have the following log entry that I am processing in PowerShell I m trying to extract all the activity names and durations using the -match operator but I am only getting one match group back. I m ...

热门标签