Home > Software engineering >  How can I tell if Docker Desktop is running in a Powershell script?
How can I tell if Docker Desktop is running in a Powershell script?

Time:06-02

I have a Powershell script in which I need to know if Docker Desktop is currently running.

I have read that one way to do it is to use docker ps and see if I get back a container list or an error message. But I'm struggling to make use of this in an actual script. I haven't worked out how to capture and act on the result correctly.

Here's what I have so far:

function IsDockerDesktopRunning()
{
    $dockerPsResult = docker ps | Out-String

    Write-Host "Result is:"
    Write-Host $dockerPsResult

    if (($dockerPsResult).StartsWith("error"))
    {
        return $false
    }
    return $true
}

$isRunning = IsDockerDesktopRunning
Write-Host $isRunning

When when it's not running, the result looks like this:

error during connect: This error may indicate that the docker daemon is not running.: Get "http:////./pipe/docker_engine/v1.24/containers/json": open //./pipe/docker_engine: The system cannot find the file specified.
Result is:

True

As you can see, it looks the output from the docker ps command gets output as it's executed and the variable isn't populated.

Is there a way to correctly capture the output? Or, should I tackle the problem a different way?

CodePudding user response:

To capture the error output as well, redirect stderr to stdout like this.

$docker = docker ps 2>&1

You can use this to determine if docker desktop is running.

if((docker ps 2>&1) -match '^(?!error)'){
   Write-Host "Docker is running"
}

CodePudding user response:

As per your comment, I feel obligated to respond. You're confused about the flow of PowerShell's execution: "the fact that the if statement has a return in it means that the final return statement wouldn't be hit.". So, here's an example:

function test ([switch]$that){
    if ($that) {
        $true
    }
    $false
}

When running the function above by itself (test), the result you would get is $false. Then, if you run test with it switch parameter -that, you will get $false, and $true. This is because, PowerShell will not stop the rest of the code execution due to an if() statements conditions being true. It will move from top to bottom unless (as mentioned in my comment), you place the return of $false in an else statement, you will get just one result of $true, or $false depending on the condition met.

To answer your question, if your error is not being captured you can ensure the error message get's redirected to the success stream using 2>&1; here, 2 is the error stream and 1 is the success stream we're telling it to point to. Finally, oyu end up with a result of:

function IsDockerDesktopRunning()
{
    $dockerPsResult = docker ps 2>&1
    if ($dockerPsResult.StartsWith("error")) {
        return $true
    }
    else {
        $false
    }
}

IsDockerDesktopRunning

Also, just noticed Doug point out the same issue and provided a proper answer as well.

CodePudding user response:

Since it doesn't seem possible to capture the error message in a variable, I've decided to switch the logic around and rely on the variable being empty.

function IsDockerDesktopRunning()
{
    $dockerPsResult = docker ps
    if ($dockerPsResult)
    {
        return $true
    }
    return $false
}

$isRunning = IsDockerDesktopRunning
Write-Host $isRunning

The unfortunate side effect is that the error message is still printed to the screen and makes things look a bit messy. But the logic works, so I'll live with it.

  • Related