Something interesting I just discovered about bash scripts and aliases

rado84

Well-Known Member
Joined
Feb 25, 2019
Messages
1,083
Reaction score
921
Credits
8,303
I just discovered something interesting about bash scripts and using them in aliases. I'm posting this for those who use aliases and scripts.

If you're using aliases and you have this exemplary alias:

Code:
alias runscript1="exec /path/to/script.sh && exit"

This turned out to be wrong and causes the shell to go nuts and it stops executing the script commands properly: especially if you've set your terminal to autoexit when the command has been executed successfully AND if the script normally expects any user input from you.

In short my discovery is that you can't have both "exec" and "exit" in the alias at the same time - it has to be either "exec" only or "exit" only.
If you have the alias as in the code above, this causes a... let's call it a "triple exit" of the shell - one exit from the terminal settings, another from the result after the "exec" command and a third exit from the "&& exit" command. And because of that triple exit the shell stops accepting any input words you type after the alias.

Let me give you an example.
In my script the command is

Code:
7z a /path/to/$1_$2.7z "$1" -mx=0 -mmt=20

When I run the alias, normally the terminal would expect two inputs from me - the name of the archive ($1) and the version numbers ($2) and the final result would be like "archivename_1.1.1.1.7z"
But I hadn't noticed that "somewhere down the road" I've added an "exit" after the first part of the alias. This caused the script to create a completely different archive: "_.7z". Needless to say this wasn't acceptable for me, so after confirming the script command actually works (outside the alias), it was a matter of time to figure out what was wrong with the alias itself. :)

Why would anyone need an "exec"? Well, because sometimes, for reasons still unknown to me, some scripts get executed but the terminal doesn't exit on its own, if you're expecting it to do so. So you have two options: adding "exec" or "exit" in the alias line. Which one would work from the first run of the alias - that's something for you to find out bc sometimes "&& exit" doesn't work either. In these cases "exec" before the path does the trick.
 


I use exec a few different ways.

I might want to replace the current shell. I might have a bash script with this line.
Code:
exec /bin/sh
That changes to a sh shell in the middle of the script.

Sometimes I want to run a command, and not return to the "main" script after running this command.
Code:
exec ls -l
The script will terminate after running this command, even if I have more code after this in my script.

You can also change the file description, you could do something like..
Code:
exec 1>output.txt
This will of course redirect standard out to output.txt. An advnatage do doing it this way is, I don't have
put all the output of the script to the output file, only the after the "exec" statement.

This is really the same as going to another shell. For example...
Code:
#!/bin/bash
echo "This is the original shell"
exec echo "This is the new shell"
echo "This will not be executed"

The last echo won't be printed, because i switched to a new shell before I reached that line.
 
alias runscript1="exec /path/to/script.sh && exit"

exec only executes the command, and then exits (like my ls -l example above) so it doesn't need an exit,
it will exit automatically after the running the command. So you are correct, you could use exec or exit, but not both.

Code:
      exec [-cl] [-a name] [command [arguments]]
              If  command  is  specified, it replaces the shell.  No new process is created.  The arguments become
              the arguments to command.  If the -l option is supplied, the shell places a dash at the beginning of
              the zeroth argument passed to command.  This is what login(1) does.  The -c option causes command to
              be executed with an empty environment.  If -a is supplied, the shell passes name as the zeroth argu‐
              ment to the executed command.  If command cannot be executed  for  some  reason,  a  non-interactive
              shell exits, unless the execfail shell option is enabled.  In that case, it returns failure.  An in‐
              teractive shell returns failure if the file cannot be executed.  A subshell exits unconditionally if
              exec fails.  If command is not specified, any redirections take effect in the current shell, and the
              return status is 0.  If there is a redirection error, the return status is 1.
 
Last edited:
But that's not mentioned anywhere, you gotta discover it for yourself. And sometimes a script doesn't want to run, if you don't force it to with "exec", which is also not mentioned anywhere.
 


Follow Linux.org

Members online

No members online now.

Top