DEV Community

Cover image for Shellscripting: Conditional Execution

Shellscripting: Conditional Execution

Darkø Tasevski on August 15, 2018

This is the second part of the series on Shellscripting. In case you've missed it, you can find the first part here. Also, note that the most of...
Collapse
 
pstadler profile image
Patrick Stadler • Edited

I really enjoy using conditions in one-liners with shell:

# if file exists, source it
[ -f $HOME/.env-local ] && source $HOME/.env-local

# if directory doesn't exist, create it
[ -d ./test ] || mkdir ./test
Collapse
 
_jack_t_ripper_ profile image
Jack t Ripper • Edited

I really like exit codes
var = $(echo "$((2+2))") & export haspid=$!
echo "$var" | grep 4
if [ $? -eq 0 ] ; then
echo "has num 4 and pid was $haspid"
else
echo "bash can't add"
fi

BASH ASH or SH
Bourne Again SH
Almquist SH
or just Shell
are pretty much the standard as I see it.

I have had to use ksh and csh, just diff formatting...

Plus another vote to bring back t9word and Remove autocorrect

Collapse
 
polyluxus profile image
Martin Schwarzer

You should use exit statuses directly, not via $?. Like

if command ; then stuff ; fi

Shorter, and save from accidentally picking up the wrong exit code.

Also var = $(echo "$((2+2))") spawns two sub shells, where you only need one: var=$((2+2))

Collapse
 
_jack_t_ripper_ profile image
Jack t Ripper

I make it a practice to always use echo and double quotes so that everything inside is resolved like the variables and maybe it is overkill but it is due to habit and also errors that I have seen that come up not using that way in various enviornments

And again putting the
if command;

May lead to again problems with variables and escaping of escapable characters.

Escaping and variables plus nested commands is why I do both practices,.

Thread Thread
 
polyluxus profile image
Martin Schwarzer

It's not just overkill, it's useless, and it might have some nasty side effects, too. Here's some more explanation: github.com/koalaman/shellcheck/wik...

If you're having trouble with your variables and escaping characters, you could always fun it in a sub shell and use that error code in the if construct. You're making it overly complicated, and prone to errors.

Thread Thread
 
_jack_t_ripper_ profile image
Jack t Ripper • Edited

Idk why everyone has to argue shit on the internet, your own citations says that using echo has its places, and I use what works for me... Not making it complicated just making something that I know works... Just because there is something that also works doesn't make how mine worked wrong...

Collapse
 
polyluxus profile image
Martin Schwarzer

As far as I remember, case does not use regex, but globbing. Similar, but different enough to make you scratch your head when something is not working.
If you need regex, nested if with =~ is the way to go.

Collapse
 
tux0r profile image
tux0r

Much of this will behave unexpectedly on the C shell which is the standard shell on BSD.

Collapse
 
puritanic profile image
Darkø Tasevski

I guess that I need to state that the most of this stuff is intended for the bash shell. I don't know many people that use csh/tcsh anyway :/

Collapse
 
tux0r profile image
tux0r

That wasn't clear, especially after the first part which recommended to use #!/bin/sh...

Thread Thread
 
puritanic profile image
Darkø Tasevski

Gonna address that later, thanks for the advice! I've never used BSD nor csh before, so I'm not that familiar with differences between distros and shells, as I'm almost exclusively using bash/zsh for my job.

Thread Thread
 
tux0r profile image
tux0r

This table might help. The ksh (AIX/OpenBSD default shell) does not differ that much from POSIX, the csh does.

Thread Thread
 
ikirker profile image
Ian Kirker
  • sh: the basics, POSIX standard
  • ash: reimplementation of sh
  • dash: port of ash
  • ksh: extensions on top of sh
  • bash: massive extensions on top of sh (mostly a superset of ksh's)
  • zsh: massive extensions on top of sh but different ones to bash

  • csh: a completely different shell to sh, contemporary in origin, mostly different syntax

  • tcsh: extensions on top of csh

  • fish: a completely different shell again, cut-down syntax and features mostly targeted at interactive users

So, yeah, it's important to specify which shell you're targeting.

Thread Thread
 
puritanic profile image
Darkø Tasevski

Thanks for the info. I've updated the posts with shell reqs. 😊

Collapse
 
thorstenhirsch profile image
Thorsten Hirsch • Edited

These one-liners are great for early exits (like in assertions), but I wouldn't use 'em in the normal program flow. So my ping script would look like this:

#!/bin/bash

[ -z "$1" ] && echo "host required" && exit 1

ping -c 1
if [ $? -eq 0 ]; then
    echo "$1 reachable."
fi

exit 0

I think it's easier to see what part of the code belongs to error handling and what's the business logic.

Collapse
 
jimmyml profile image
Jimmy Maturana

Thanks for you post. It's very clear and usefully.
I think that here you have a bit error:

MY_SHELL="zsh"

if ["$MY_SHELL" = "zsh"]
    then
        echo "You are the zsh shell user!"
fi

You forget the space after an before [].

Sorry by my english.

Collapse
 
puritanic profile image
Darkø Tasevski

Thanks for noticing, I'll fix it right away!