sh shell scripts have an ugly syntax ?

«if» in programming langage did not match the «if» in natural langage.
if [ elefant -eq flying ] ; then do_walk elefant fi
Bash:
[elefant -eq flying ] && do_walk elefant

I see in a lot of code this kind of things : (I was a senior code reviewer in past job)

Code:
if ( condition ) then return true else return false

Obviously, the real code is more complicated, but you maybe see the same things.

When I was student, a professor say «object programing was invented to replace if statement»

And it is not as falsy as this sound...
 
By the way, if you want to write zsh scripts as portable as possible, the first line should look like this:
Code:
#!/usr/bin/env zsh
That’s because the location of the zsh binary can differ. Most Linux systems have it in /usr/bin, sometimes it is somewhere under /opt, and the BSDs usually have it in /usr/local/bin. When using the env(1) trick, it doesn’t matter where the zsh binary is located, it just has to be somewhere in the users $PATH.
That env trick has advantages and disadvantages. Advantage: the script is more likely to work, because the user probably has their path set correctly.

Disadvantage: Whether the script works or not now suddenly depends on a user setting; a harmless-looking change to the PATH variable, and suddenly things start breaking. Another disadvantage: there may be different versions of the same program installed in different places, and using the env trick relies implicitly on people ordering things sensibly in the path.

I'm not saying to never use /usr/bin/env, just warning people that a little discipline is still required.
 
Bash:
[elefant -eq flying ] && do_walk elefant
I don't like that. Same with the perl idiomatic thing: "do_something || die". It relies on the short-circuit property of evaluation, which I find unintuitive when reading the code (although the perl idiom has become very common, so one recognizes it).

Code:
if ( condition ) then return true else return false
Yeah, that's bad. Just as bad is the following:
Code:
if (boolean_variable == True) ...
and even worse is:
Code:
if (boolean_variable == False) ...

There are many ways to write bad code.
 
In any programming language, it is always a good idea to craft one's code so it gets as close as possible to English sentences.
Benefits are invaluable and, as long as there's no tax on source file size, there's no penalty.
 
Some unreadability is sometimes due to overdue of syntactic sugar.
Ralph & Hakaba, what is good practice for the examples you've given.
 
In bash i had one , notice the difference between [ and [[ , I was surprised.
Code without an error:
Code:
if [ "$s2" == "$s2" ]
    then echo "equal"
fi

if [[ "aaa" < "bbb" ]]
    then echo "in order"
fi

Whereas this gives gave error:
Code:
if [ "aaa" < "bbb" ]
    then echo "in order"
fi
>>> bbb: No such file or directory
 
A bash one :
Code:
age=9
echo $age
case $age in
[0-15])
    echo "Too young"
    ;;
*)   
    echo "Too old"
    ;;
esac

Prints Too old
 
< and >can only be used as relational operators between [[ and ]].
Otherwise, they are interpreted as redirections.

Man pages are clear: see section CONDITIONAL EXPRESSIONS in "man bash" for [[ ]] and "man test" for [ ].

Whereas this gives gave error:
Code:
if [ "aaa" < "bbb" ]
    then echo "in order"
fi
>>> bbb: No such file or directory
 
When in Rome, do as the Romans do (St. Augustine)

I've started a simple hobby project some years ago (rolling up until now), using C, basically to keep my mental cogs spinning. After playing with it I realise that I was not programming but scripting. Using system facilities - ls, sort, write, etc - calling it with system(). "Plumbing" in essence.

So I started with bash... Ok... But I had same sensation of "ugliness" described at thread start. And "plumbing" too much avoiding idioms of bash and connecting sed, awk, the "terrible 2>&1"...

So I restarted everything using the "fancier, whistler and bell'ser" python... Well, after some lines of code, I decided to run it in other system... Ooops... I've to install python... Configure python... Equalize python... Diaper changing python... Powdering python... I was not programming or scripting anymore, but tweaking things!

After some frustration... I restart again with bash. I needed some associative arrays to keep things tidy... Well it works fine in bash (despite of awful and confusing syntax). I detect it was my problem not bash problem. And finally I started with awk and realise again that I was doing programming again, not scripting anymore.

So I started using FreeBSD and everything changes once again... Bash on FreeBSD seems not to be welcome. I suspect that I should have used shell and Posix (like a recommedation above).

At end my perception is if you are doing too much tweaking or jugglery with your code, your real need is to revise that code and split (and test) in little parts. Script where to script, program where to program and connect those pieces with json.

If you are a programmer you are supose to deal with logic. Languages are tools to deal with logic. Languages are not the road or destiny, but the car. It pays learn to drive!

Some tools are designed to accomplish "culture" system's needs. You have to be flexible enough because modern systems are very flexible these days. If you try impose your needs chances are you'll be in hot water.

Roughlly all my problems come from the stubborn of want to see things work quick and the frustration to deal with dirtness of shortcuts ... Avoiding the wise of learning by R(&U*)TFM.

*(and understand)
 
So I restarted everything using the "fancier, whistler and bell'ser" python... Well, after some lines of code, I decided to run it in other system... Ooops... I've to install python... Configure python... Equalize python... Diaper changing python... Powdering python... I was not programming or scripting anymore, but tweaking things!

Agreed. While i hold nothing against python in general i don't think it's an ideal choice for system scripting. It's way to heavyweight which on a regular system might not be really noticeable but as soon as it comes to minimal setups every dependency on python (or perl for that matter) that exists just to run some rather simple script becomes an annoyance and as you said python doesn't always equal python either.

Bash on FreeBSD seems not to be welcome. I suspect that I should have used shell and Posix (like a recommedation above).

I personally don't think bash in itself is bad or anything. The problem is more with how bash has managed to become synonymous with shell scripting and a lot of people not even realizing that there might be more portable (and also less resource intensive) ways to solve the problem they are facing. This is a obviously particularly widespread in the linux community where bash is practically everywhere and it's easy to forget that this actually isn't the norm (there was even a time when Debian had linked /bin/sh to /bin/bash because not doing so would risk breaking it's boot scripts...).

Still when a certain feature noticeably improves a script and there is no reasonable way to emulate it and/or reorganize the code to avoid the need i don't see anything wrong with targeting bash (or *ksh, or whatever shell supports your desired feature). On the contrary i will be quite happy you didn't chose python or perl. In my eyes putting a lone additional executable on my system is nothing compared to a full blown scripting language environment even if it's only use is to run a single script.
 
Powdering python... I was not programming or scripting anymore, but tweaking things!

This is so true. Whenever I see a potentially useful python program, the README is always filled with this wild goose chase of dependency management and outright faffing. Most of it is outside of the OS package manager too (and using PIP) which makes maintenance a chore.

It is a shame because the language itself isn't too bad. It is fairly sane and boring (which is a good thing!).
I can also see why it is like this, for example it cannot natively connect to C libraries (basically the underlying OS) so you need bindings (via PIP) which are usually only maintained by a single person in their free time and often suffer from bitrot.

<ramble>
I think the only way to solve this is to include a tiny C compatible compiler within Python itself. Not because C is your end goal but only so that it can consume C headers / libraries and connect to the underlying OS. I strongly suspect this is what has contributed to C++'s success. If C++ couldn't access C libraries, it would be fairly dead in the water.
 
Could I say use [[ ]] always and never [] even if it means a little more typing on the keyboard ?

If your scripts are bash-only, why not?

I had the same idea not so long ago.
Then, I tried FreeBSD and realized bash was not in base, so I tried and rewrite my scripts with sh to reduce their dependencies.
I turned out this exercise improved the readability of my scripts because most bash internals/extensions I was using where provided by expr, sed and tr.
The lines in my scripts are now longer, but easier to read (and thus maintain) than bash-specific stuff.
It also forced me to be clearer about the distinction between scripting and programming, which improves my productivity.

In the end, I consider NOT using bash a blessing in disguise. ;)
 
Could I say use [[ ]] always and never [] even if it means a little more typing on the keyboard ?

While i don't know the answer to your exact question the reverse is certainly true. I'd say i've written my fair share of shell scripts over the years and i can't remember a single time when i felt limited by [ ... ] / test but then i've hardly ever used bash so maybe i just don't know what i have been missing out on.

To be in base in not really that important.
mksh has only one dependancy /lib/libc.so.7

There is also a variant named lksh made for scripting which supposedly is even more lightweight but i don't know if there is an easy way to install it on FreeBSD. It seems the mksh port has no option to build it and it does not have it's own port either. Not that this is much of a problem with mksh itself being quite efficient already and also having dual use as a (in my opinion) pleasant interactive shell.
 
Could I say use [[ ]] always and never [] even if it means a little more typing on the keyboard ?
Why? What advantage does [[ give over [?

In the old days, it ran faster. Today, with good caching in the file system, and very optimized fork/exec, I doubt that it makes a measurable difference. Today, the restricted resource is usually not CPU time, but human time, in particular human time spent debugging, porting, organizing. So I prefer to write my shell scripts relatively simple, using a sort of "lowest common denominator" between shells. While I do use bash (even on FreeBSD, even as my login shell, even for root in spite of the recommendation to not do that), I try to write my scripts using sh.
 
Isn't '[' always built in for sh anyway?
The builtin manpage suggests it is. So [[ shouldn't offer any speed advantage.
It is a builtin for sh (in the sense of FreeBSD's default /bin/sh) and for bash. I knew about bash, but I actually had to check for sh.
 
Isn't '[' always built in for sh anyway?
It was added (probably!) in System III shell (1981):

> Seventh Edition (aka Version 7) Unix shell, (1979)
Quote from https://www.in-ulm.de/~mascheck/bourne/#version7
no "[" built-in available (even not as external command on Version 7), but only the external "test"
manpage: https://www.in-ulm.de/~mascheck/bourne/v7/

> System III shell (1981)
Quote from https://www.in-ulm.de/~mascheck/bourne/#system3
built-in "test", aka "[", added (the latter actually was always existent in code, but commented out)
manpage: https://www.in-ulm.de/~mascheck/bourne/sys3/
 
I don't like that. Same with the perl idiomatic thing: "do_something || die". It relies on the short-circuit property of evaluation, which I find unintuitive when reading the code (although the perl idiom has become very common, so one recognizes it).
I don’t like that either. But I think “die … unless …” is much worse. Introducing the keyword “unless” is one of the many mistakes in Perl.
 
Why? What advantage does [[ give over [?
Cleaner syntax, less ambiguity, lower risk of “surprises”. I always use [[...]] when I use zsh or bash. Of course, if I need to stay compatible with FreeBSD’s /bin/sh, I’m restricted to use [...] only.

By the way, [[...]] is a shell keyword, while [...] is a built-in command. Normally that doesn’t make a difference, it only matters when you’re trying to do strange things, for example running it in the background (which works for [...] because it’s executed like a normal command, but it doesn’t work for [[...]]).

The last shell I know that did not have [...] built-in was Solaris’ /bin/sh. So, each time a script did if [...]; then it had to fork(2) + execve(2) an external command with all of its overhead. Consequently, scripts that did that very often ran very slow. In such cases, replacing #!/bin/sh in the script’s first line with #!/usr/xpg4/bin/sh gave a considerable speed-up.
 
Back
Top