How to use timeout command to terminate a command and proceed accordingly

The aim of this page📝 is to share my solution to the problem that I want to allow users into a Docker box only if the attempt to authenticate against Hashicorp Vault succeeds.

Pavol Kutaj
2 min readDec 29, 2022

In other words, only if they are in VPN. It’s a bit of a leap of faith, I know. To diagnose if I am in VPN, I just use a blunt mechanism of timeout — if the program runs for > 5s, it follows that you are not in the VPN, which is another leap, I know. But hey, this is an internal and team-specific box, so it should be a good-enough measure. The abstract (therefore interesting:) question remains: how to timeout a program in bash and make a case analysis based on that, i.e. if timed out do something (exit early) and if not timed out, just run along the happy path.

Use timeout command and exit quickly if timed out, which is confirmed by exit code 124

  • Use timeout command
  • ⟹ time runs out and the command that follows is terminated; from timeout --help
Usage: timeout [OPTION] DURATION COMMAND [ARG]...
Start COMMAND, and kill it if still running after DURATION.
<!-- EXAMPLE -->
timeout 2s ping google.com
  • If any command times out, the timeout returns error code 124
EXIT status:
124
if COMMAND times out, and −−preserve−status is not specified

timeout(1) — Linux manual pages

  • If that happens, so I just explain myself and terminate
timeout 5s vault login -method=github token="${GITHUB_TOKEN}"
if [[ $? == 124 ]]; then
echo "ERROR: Authentication timed out after 5s!"
echo "~~> VPN is a prerequisite — please connect and try again"
exit
fi
  • If no, and command returned 0 (all good, it did not time out) ⟹ just go on

Just for fun, it is possible to use --preserve-status and then go with error_code 143

  • If I use --preserve-status flag, the failed command in my case generates exit code 143
  • Exit code 143 is returned by SIGTERM signal, which is basically a signal for grafeful termination

is a generic signal used to cause program termination. Unlike SIGKILL, this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate. The shell command kill generates SIGTERM by default.

Termination Signals (The GNU C Library)

  • Say you want to do this with a ping command (echo $? checks for the last exit code)
~$ timeout --preserve-status 2 ping google.com
PING google.com(prg03s13-in-x0e.1e100.net (2a00:1450:4014:80f::200e)) 56 data bytes
64 bytes from prg03s13-in-x0e.1e100.net (2a00:1450:4014:80f::200e): icmp_seq=1 ttl=116 time=18.4 ms
64 bytes from prg03s13-in-x0e.1e100.net (2a00:1450:4014:80f::200e): icmp_seq=2 ttl=116 time=16.0 ms
~$ echo $?
143
  • In my case, I’d just add the flag and replace 124143
timeout --preserve-status 5 vault login -method=github token="${GITHUB_TOKEN}"
if [[ $? == 143 ]]; then
echo "ERROR: Authentication timed out after 5s!"
echo "~~> VPN is a prerequisite — please connect and try again"
exit
fi

LINKS

--

--

Pavol Kutaj

Today I Learnt | Infrastructure Support Engineer at snowplow.io with a passion for cloud infrastructure/terraform/python/docs. More at https://pavol.kutaj.com