Introduction
Some programs operations may include commands that can allow you to script them from your shell, such as bash. Moreover , some programs allow for a whole set of scripting capabilities within itself, but been able to ultimately chain them with some interpreter logic in order to perform some more complex actions.
Tmux case of study
For instance in tmux
terminal multiplexer for Linux, and other shell systems, the program has such a wide array of commands that customize the user experience, which can be checked on its manpage man tmux
Say that I want to display a message, this command can be runned in three different places: - Inside the program - In the configuration file - From the command line interpreter (the shell, probably bash)
Say for the command
display "Hello World"
Will show that message in the status bar of the program.
Running it Inside the program would be
:display "Hello World"
Running it from its config file $HOME/.tmux.conf
just append on it the following line.
display "Hello World"
In order to run it from the shell you need to just append the tmux
to it and it will be runned.
Ommitting some program specific particularities the former command can be runned as
$ tmux display "Hello World"
This opens up a whole new dimension of scripting capabilities by hooking up shell scripts performing program calls in and out, creating some more complex form of logic and functionalities.
A syntax colission
Been tmux
a complex program itself, the commands can be taking quite sophisticated forms that can collide with the syntax of shell.
Let’s take the example of the tmux
command bind-key
which can bind to certain key-presses some actions.
Simplified and in a nutshell the command can be explained as
bind-key <key> <command01> /; <command02> /; ... /; <commandn>
So say I do
bind-key a display -p "Hello" \; display -p "World"
That would be working from Inside the program , and in its configuration file, but as soon as you try to execute it in the shell
$ tmux bind-key a display -p "Hello" \; display -p "World"
World
And by pressing a , I will only get the “Hello” message
The reason being is that the shell is “swallowing” the \;
characters , saying , \ for escape the next character, ; for sequencing the execution of the commands.
Thats why it prints then “World” to stdout
One way of solving this situation is to escape these succession of characters by quoting them , according to man bash
Quoting is used to remove the special meaning of certain characters or words to the shell.. So that is our ally
tmux bind-key a display -p "Hello" '\;' display -p "World"
Will be the command corrected now
List of conflicting characters
As you can see, you need to be careful with what the shell can interpret, in terms of characters telling the shell to perform a certain expanwould sion, or to escape some characters etc…
Doing a ‘man bash’ checking for different expansions and etc… having an in-depth understanding of those rules would be the ultimate objective giving you a clear understanding on what conflicts may arise on such a “translation”, but in a nutshell It is important to pay attention to the following characters.
- Quotes : Single (‘) and double (“)
- Escape characters: Such as the backslash (‘\’)
- Semicolon (;)
- Ampersand (&)
- Pipe (|)
- Dollar Sign ($)
- Parentheses (()) and Curly Braces ({})
- Brackets ([]) and Wildcards (*, ?, [])
- Whitespaces
- Quotes in Quotes:
- Hashtags for Comments #.