M. Barbieri
M. Barbieri

Reputation: 542

If statements not executing after function call in bash

I have a bash script that looks like the following:

#!/usr/bin/env bash
set -x

function run_container {
    CONTAINER_NAME=$(date +%s | sha256sum | base64 | head -c 16)
    echo "running: docker run -i --name $CONTAINER_NAME $REGISTRY/${1}"
    docker run -i --name $CONTAINER_NAME $REGISTRY"/"${1}
    echo "removing: container $CONTAINER_NAME from ${1}"
    docker container rm $CONTAINER_NAME
    echo "removing:  image $1"
    docker image rm ${REGISTRY}"/"${1}
    echo -e "\nDone with container ${1}\n\n\n"
    return 0
}


GCC_BUILD=${1}
GLIBC_BUILD=${2}
KERNEL_BUILD=${3}
POSTGRESQL_BUILD=${4}
PYTHON_BUILD=${5}
REINSTALL_PACKAGES=${6}
RUBY_BUILD=${7}
SEGMENTED_DOWNLOAD=${8}
UBUNTU_RSYNC=${9}


echo $GCC_BUILD
echo $GLIBC_BUILD
echo $KERNEL_BUILD
echo $POSTGRESQL_BUILD
echo $PYTHON_BUILD
echo $REINSTALL_PACKAGES
echo $RUBY_BUILD
echo $SEGMENTED_DOWNLOAD
echo $UBUNTU_RSYNC

REGISTRY="myregistry.com"


if [[ "$GCC_BUILD" == "true" ]]; then
    echo "Running GCC_BUILD"
    run_container "gcc-build"
fi

if [[ "$GLIBC_BUILD" == "true" ]]; then
    echo "Running GLIBC_BUILD"
    run_container "glibc-build"
fi

if [[ "$KERNEL_BUILD" == "true" ]]; then
    echo "Running KERNEL_BUILD"
    run_container "kernel-build"
fi

if [[ "$POSTGRESQL_BUILD" == "true" ]]; then
    echo "Running POSTGRESQL_BUILD"
    run_container "postgresql-build"
fi

if [[ "$PYTHON_BUILD" == "true" ]]; then
    echo "Running PYTHON_BUILD"
    run_container "python-build"
fi

if [[ "$REINSTALL_PACKAGES" == "true" ]]; then
    echo "Running REINSTALL_PACKAGES"
    run_container "reinstall-packages"
fi

if [[ "$RUBY_BUILD" == "true" ]]; then
    echo "Running RUBY_BUILD"
    run_container "ruby-build"
fi

if [[ "$SEGMENTED_DOWNLOAD" == "true" ]]; then
    echo "Running SEGMENTED_DOWNLOAD"
    run_container segmented-download
fi

if [[ "$UBUNTU_RSYNC" == "true" ]]; then
    echo "Running UBUNTU_RSYNC"
    run_container "ubuntu-rsync"
fi

echo "Finished build suite."

Once an if statement matches, the function executes, but the script ends. So for example if the GCC_BUILD and GLIBC_BUILD variables are true, the script will perform the actions in the run_container function for the GCC_BUILD, but not for the GLIBC_BUILD.

If I remove the run_container call within the if statements, and just leave the echo there, everything runs as it should.

Is there something about the function that makes the script exit?

UPDATE:

Since I have set -x on here is what gets printed for trace:

:18+GCC_BUILD=false
:19+GLIBC_BUILD=false
:20+KERNEL_BUILD=false
:21+POSTGRESQL_BUILD=false
:22+PYTHON_BUILD=true
:23+REINSTALL_PACKAGES=false
:24+RUBY_BUILD=true
:25+SEGMENTED_DOWNLOAD=false
:26+UBUNTU_RSYNC=false
:29+echo false
:30+echo false
:31+echo false
:32+echo false
:33+echo true
:34+echo false
:35+echo true
:36+echo false
:37+echo false
:39+ARTIFACTORY=myregistry
:42+[[ false == \t\r\u\e ]]
:47+[[ false == \t\r\u\e ]]
:52+[[ false == \t\r\u\e ]]
:57+[[ false == \t\r\u\e ]]
:62+[[ true == \t\r\u\e ]]
:63+echo 'Running PYTHON_BUILD'
Running PYTHON_BUILD
running: docker run -i --name OTQ0YzJjZTU4YWQy myregistry/image
:64+run_container python-build
::6+date +%s
::6+sha256sum
::6+base64
::6+head -c 16
:6+CONTAINER_NAME=OTQ0YzJjZTU4YWQy
:7+echo 'running: docker run -i --name OTQ0YzJjZTU4YWQy myregistry/image'
:8+docker run -i --name OTQ0YzJjZTU4YWQy myregistry/image

Done with container python-build

:9+echo 'removing: container OTQ0YzJjZTU4YWQy from python-build'
:10+docker container rm OTQ0YzJjZTU4YWQy
:11+echo 'removing:  image python-build'
:12+docker image rm myregistry/image
:13+echo -e '\nDone with container python-build\n\n\n'
:14+return 0

I cannot post all output since there is a lot, but these are the lines that print from xtrace

Upvotes: 0

Views: 172

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295766

If your script unexpectedly stops executing after a program that -- like ssh, ffmpeg, or docker run -i -- can read stdin or modify terminal configuration, one step you want to run in debugging is to redirect that program's stdin from /dev/null.

To do that (and address some issues with names having spaces in the process), change:

docker run -i --name $CONTAINER_NAME $REGISTRY"/"${1}

to:

docker run -i --name "$CONTAINER_NAME" "$REGISTRY/$1" </dev/null

...or, if you need to isolate the command from the terminal more completely, you can (at some efficiency cost) give it a non-TTY stdout and stderr:

docker run -i --name "$CONTAINER_NAME" "$REGISTRY/$1" </dev/null > >(cat) 2>&1

...though I'd usually remove -i before going that far.

Upvotes: 1

Related Questions