# Bash #1 - Execution Relay

Posted April 25, 2021 ‐ 3 min read

The bash shell is somewhat like the lingua-franca of the UNIX-based shell scripting world, as nothing else manages to displace it. The usefulness of a language is significant if it is omnipresent.

In this post I begin a series about programming in bash. Its earlier incarnation sh is less of a concern to me because bash can be found in almost in every place where sh is present.

The pitfalls in bash-programming for the initiate or non-frequent shell script programmer are numerous. However, they are easy to avoid by just sticking in to some rules.

## Relaying execution

Occasionally you want to relay an execution of one program to another. Possible reasons: providing arguments, environment variable hacks, path, and so forth.

For example, let's create a mutex around another program using flock, a program to manage locks from shell scripts.

flock has the following syntax:

 flock [options] file|directory command [arguments] 

From this, it is apparent that we would need to relay arguments to the executed program.

## Relaying arguments (always use "$@"!) It is important to understand the difference between the following expressions: • $*
• $@ • "$*"
• "$@" Let's test this with a simple bash script. The script executes Python to see what list of strings was actually relayed as an argument list.  echo python -c "import sys; print(sys.argv[1:])"$* python -c "import sys; print(sys.argv[1:])" $@ python -c "import sys; print(sys.argv[1:])" "$*" python -c "import sys; print(sys.argv[1:])" "$@"  Execution result:  $ bash test.sh foo bar 'hello world' \? ['foo', 'bar', 'hello', 'world', '1', '2', 'm'] ['foo', 'bar', 'hello', 'world', '1', '2', 'm'] ['foo bar hello world ?'] ['foo', 'bar', 'hello world', '?'] 

From this we can see there's only one good option. Let's break it down to what happens:

• $* - don't quote arguments, perform wildcard expansion and then relay • $@ - same