1.
You're referring to the
shebang (
Hash Bang). The
#!/bin/sh
is for the Bourne Shell (or derivatives, such as DASH), which isn't the same at all as using BASH, because the syntax and general capabilities of the shells are quite different.
Whether or not you need the
shebang depends on
how you or other users will be executing the script. For example, you can omit the the
shebang if all you're going to do is execute it with, for example
sh bourne_script.sh
, but if the script (the file) has the
execute bit set for the user, then you can, for example, run
./bourne_script.sh
. You may also want to add the shebang for an editor's syntax highlighting, such as in Vi-IMproved, and/or to allow both forms of execution. When sourcing (
.
or
source
), the shebang isn't needed.
1000 wrote:
If someone copies the script to another system with a different shell, the script may not work properly.
The user on that other system would need access to that shell in that location, or a shell abiding by the same applicable rules, such as DASH's intention to comply with Bourne Shell syntax.
2.
1000 wrote:
Sometimes for example, command "printf" is more preferable because is compatible with POSIX.
I always use the
printf
builtin -- note that there is a GNU alternative, often installed by default at '/usr/bin/printf'. Not only is
printf
vastly superior to
echo
, but it's more consistent, reliable, and similar to
printf
in other languages, such as C, AWK, Perl, Python, etc.
That said,
echo
can be really useful as a one-off, for debugging, due to it taking all (except accepted flags, of course) arguments as something to
echo. This is useful for knowing to what variables expand, for example.
You demonstrate the use of the
%b
format specification in
printf
, but it would've been better to use
%s
, for a
string, where
%b
is for a string from which you wish to expand
escape sequences, such as
\n
and
\e[1;31m
.
3.
As you explain, a common practice, one in which I often partake, is to use a
shebang like:
It doesn't allow you to supply flags to BASH, but it's a more portable solution, without relying on BASH being in a specific location. For example, in Linux, BASH is typically '/bin/bash', but in Mac, it's somewhere like '/usr/local/bin/bash'.
Regarding the security issue of
PATH: honestly, if you're so compromised, then you have many more far more serious problems. It's down to the user to ensure they manage their system properly, IMO, not the developers.
4.
Ah,
ShellCheck. I'm of the exact opposite opinion, here. I strongly believe ShellCheck typically encourages people not to understand the shell and its limitations properly.
I cannot tell you how many times I've come across projects on, for example, GitHub, who's devs disregard PRs (
pull requests) simply because the code clashes with ShellCheck, yet it's perfectly valid code and there are no actual issues. The other devs just don't care, because they don't
understand what's going on. They'll argue tooth-and-nail that what I'm doing is wrong, when it's not and it's all well-documented in places like manual pages, it's just that ShellCheck specifically is telling them it's 'wrong'.
Blindly following ShellCheck is something I will never
ever recommend. The only time I think something like ShellCheck might be useful, is for very large projects, for experienced shell programmers to get an overview of any potential problems they may have overlooked, especially when multiple people contribute to the code. That said, I'd argue that's why we have tester scripts and debugging code in our larger and/or more complex projects.
I never used anything like ShellCheck in any language. I rely on the language itself to tell me when something is wrong. I taught myself everything I know about programming, and I honestly believe I was better off for it. I found out myself, through experience, why, for example, using
[ CONDITION -a CONDITION ]
can be problematic; instead of relying on something to nag me about it, I experienced it first hand and did my own research on the matter. Yet, ShellCheck will light up like a Christmas tree, encouraging
their way of doing things. Although ShellCheck will give an explanation, I imagine that people typically won't properly understand or even read it, hence everything I've said above.
Projects I come across from people enforcing ShellCheck in their projects typically have wildly inefficient code and demonstrate a limited understanding of the shell in which they're programming.
YMMV, but this has been my incredibly frustrating experience over the years. Knowing exactly what you're doing from years of experience and research, only to have someone with a naive understanding of the code come along with ShellCheck, telling me the code I spent time contributing to a project is all wrong because ShellCheck says so, is unbelievably aggravating, and why I don't tend to put my time in such projects.
That turned into a bit of a rant -- sorry.