Sunday, April 19, 2026

Read-Only Variables in Bash

 

Bash has a little known concept of read-only variables.  When specifying 'readonly' during a variable assignment prevents the variable from being reassigned.

 For example;

 1  #!/bin/bash

2

3  readonly x=0

4  echo $x

5  x=1

6  echo $x

Line 3 specifies a read-only assignment of variable x to 0, an attempt to reassign on line 5 will be disregarded and produce an error message.  The error doesn't prevent continuation of the script however.

 

::::::::::::::

Sunday, April 12, 2026

Detect Command Timeouts using Bash

 A common, and often overlooked, need for scripting is addressing hanging, or unresponsive commands.  What should your script do if one of it's ste

ps takes much, much, much longer than expected?  A hanging, or unresponsive, subprocess will result in a hanging job which in turn can prevent oth

er jobs from running.  Let's spend a bit of time how to address such an need.

 

The 'timeout' command is provided by the coreutils package, often readily available on default installation for most distributions.

 

$ sleep 10

$ echo $?

0


 

Execution of subprocesses generally set a return code, zero or non-zero, often zero indicating successful execution of the command, non-zero return codes if it failed for some reason.  The above command sequence will execute a sleep command (for 10 seconds), the second command echoing the return code.  Assignment of $? to zero indicates the sleep command executed successfully.

 

So, what if we wanted to prevent a hanging command to go undetected and/or prevent the rest of a script from running.  Let's say we want to enforce a command takes no longer than 5 seconds.
 

$ timeout 5 sleep 10

$ echo $?

124


 

After 5 seconds, the command terminates, the return code 124 indicates the command timed out.  Usage of this allows setting hard constraints on how long a command is allowed to run before terminating or being terminated.  The return code allows determining if the command timed-out.
 

Cheers.

Sunday, April 5, 2026

Synchronizing Completion of Concurrent Commands

 

Running concurrent commands in a script generally is done by executing processes in the background.  Numerous commands can be spawned concurrently then synchronized by waiting for some, or all, of them to complete before proceeding or terminating the parent script.

     1  #!/bin/bash

     2

     3  sleep 10 &

     4  pId1=$!

     5

     6  sleep 2 &

     7  pId2=$!

     8

     9  sleep 3 &

    10  pId3=$!

    11

    12  echo "waiting for jobs to complete"

    13  #wait ; #--wait for all jobs to complete

    14  wait $pId1 $pId2 $pId3 ; #--wait for specific jobs to complete

 

In the above script, a sequence of sleeping {10, 2, and 3} seconds are executed in sequence, each in the background.  The longest running command  (e.g. 10 seconds in this example) should take 10 seconds, the other two commands concluding earlier.

We can test the proper exection, the script completing in ~10 seconds by timing the execution as follows:

$ time ./foo

waiting for jobs to complete

 

real    0m10.008s

user    0m0.003s

sys     0m0.004s

$

bash-4.1$