Aliance
Aliance

Reputation: 867

The result of docker exec command

I need to know in my shell script the output of some docker exec commands, for example I have an nginx container and in my script I run:

docker exec -it containerName /etc/init.d/nginx configtest

I want to continue script execution only if nginx config test is success, not when fail.

I've tried out to use $?, but it is 0 even then configtest output is fail (because docker exec is successfully executed, as I understand).

Upvotes: 28

Views: 31074

Answers (6)

Eugene
Eugene

Reputation: 2711

While all other solutions (except @VonC one) rely on shell (that may be absent in the container), as of 2024 (docker version 27.0.3), docker exec returns exit code of the process:

$ docker exec CONTAINER_ID sh -c 'exit 100' ; echo $?
100

The code is here, and it seems to exist from year 2016, version 17.06

Upvotes: 2

eleuteron
eleuteron

Reputation: 1983

A new version ready to test to run a bash command:

docker exec -t -i oracle bash -c "echo hola && exit"
hola

Upvotes: 0

Lukasz Dynowski
Lukasz Dynowski

Reputation: 13700

If you don't want to immediately respond to exit code returned from a process triggered by docker exec command, you could do something like this.

docker exec my-app-container /app/scripts/test.sh
UNIT_TEST_EXIT_CODE=$? # Get exit code from last command (/app/scripts/test.sh)
... # do some stuff after unit testing 
exit $UNIT_TEST_EXIT_CODE

I used this approach in the context of CI/CD pipelines.

Upvotes: 1

conradkleinespel
conradkleinespel

Reputation: 7007

I found this to be working quite well:

docker exec -t -i my-container sh -c 'my-command; exit $?'

Upvotes: 21

anubhava
anubhava

Reputation: 786146

Translating my comment into an answer. This should work:

docker exec -it mynginx /etc/init.d/nginx configtest && echo "pass" || echo "fail"

It works for me.

Upvotes: 13

VonC
VonC

Reputation: 1329452

The api/client/exec.go#L97-L100 does get the exit code:

var status int
if _, status, err = getExecExitCode(cli, execID); err != nil {
    return err
}

That comes from api/client/utils.go#L84-L97

// getExecExitCode perform an inspect on the exec command. It returns
// the running state and the exit code.
func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) {
    resp, err := cli.client.ContainerExecInspect(execID)
    if err != nil {
        // If we can't connect, then the daemon probably died.
        if err != lib.ErrConnectionFailed {
            return false, -1, err
        }
        return false, -1, nil
    }

    return resp.Running, resp.ExitCode, nil
}

So if your command fail, you will get the exit code.
Although, as mentioned here, you could use nginx -t instead of configtest.

Upvotes: 6

Related Questions