This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--JmDNeoq8Ebv1nqkSd8BNHALVJ2SuOPi93
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
El 21/02/14 00:37, Dan Kenigsberg escribi=F3:
On Thu, Feb 20, 2014 at 09:52:23PM +0100, David Caro wrote:
> Hi everyone!
>
> Lately I've had a hard time to properly review some patches containing=
shell
> scripts to manage our infrastructure because there's no
guidelines. So=
I created
> a wiki page with a proposal [1]. It's made up as a mix of
some already=
existing
> guidelines.
>
> The reason to wrote a bash style guide and not a shell stile guide is =
because
I
> think that bash is widely adopted (default GNU shell) and
provides eno=
ugh
> advantages to sacrifice some portability. I think that most of
our mai=
ntenance
> and management scripts will never be run on non-GNU OSes.
=20
What are the advantages in your opinion? I like the $() construct and
local variables. Associative arrays can come up handy.
* Less prone to errors:
- [[ ]] builtin constructs make it really easy to avoid having errors w=
hen
spaces are in the tested variable:
myfile=3D"/thi/is my/file"
[[ -f $myfile ]] <- this does not break and works as expected
[ -f $myfile ] <- this breaks
- Long options are really nice and make code clearer
- Arrays are useful
- Associative arrays are useful too
- String expansions with brackets
mv myfile{,.bkp}
- Pattern substitution:
${myvar/mypatt/mysub}
- Substring expansion:
${myvar:offset:length}
- Indirect variable expansion (don't use it if you don't need it, like =
eval):
${!myvar}
- $PIPESTATUS array, with the return codes of the commands executed in =
a pipe
- options in echo (echo -e, echo -n, ...)
- local variables definition, there's no local in POSIX:
local a b c <- this is not POSIX
- source command (a lot clearer than '.', harder to confuse with execut=
ion)
- select command to create menus
- the time builtin (not a builtin in POSIX)
- Process substitution redirection:
foo <( bar )
- '=3D=3D' equality test instead of '=3D' (A lot more readable and
less=
confusing)
- '<>' lexicographical comparison
- Check if 2 files are the same hard link:
[[ $file1 -ef $file2 ]]
- Redirecting stdin and stdout:
&>, >& and &|
- duplication and closure of file descriptions:
m>&n-
- Herestrings ('<<<')
- A lot of the shopt options
- FUNCNAME to get current function name
- REGEXP matching test (=3D~)
Those are a few, there are more differences but some of them I don't reco=
mmend
(that's why we are creating a style guide, to use only the ones that real=
ly help)
=20
>
> POSIX compliance should be only used when really needed, for example, =
scripts
to
> build a specific project, that might be run on non-GNU based
systems i=
n the far
> future.
=20
I have the opposite sentiment - diversions from the standard should be
kept small and well-justified.
I heard this before from Alon, in my opinion, both of you have the wrong =
idea of
what a standard is and when to apply it.
POSIX standard is a standard created to allow portability between operati=
ng
systems, that's it's goal. The infrastructure scripts will most likely ne=
ver be
run outside the GNU family of operating systems
(fedora/centos/ubuntu/debian/suse/gentoo ...) so the portability is not
something that matters.
Thus, the application of the POSIX standard is too restrictive. Imagine i=
t like
building your house in Norway with the same standards that are used in To=
kyo,
you don't need protection from eathquakes, you need heat efficiency.
The same way, we don't need portability, we need flexibility and error av=
oidance.
As I said also, at the end of the script and at the end of the wiki, if y=
ou are
gonna distribute a script with the product, then POSIX standard is the on=
e that
should be applied.
=20
>
> This thread is to start a discussion about it so please, share your op=
inions
and
> concerns (and proposals).
>
>
> [1]
http://www.ovirt.org/Bash_style_guide
=20
Could you detail where [1] is different from the
http://wiki.bash-hackers.org/scripting/style that it cites?
Some of the differences are:
- Indentation (I said 4 spaces and that the consistency in using tabs o=
r
spaces throughout the script is more important than using spaces)
- I let case constructs to fit in one line if they are short (one comma=
nd)
- Added the 'local' usage on the function variables
- Recommended to use function parameters instead of global variables
- Recommended to specify a return statement explicitly
- Using builtins instead of external commands when possible
- Added portability note
Most of those are from here, a german linux user group:
http://lug.fh-swf.de/vim/vim-bash/StyleGuideShell.en.pdf
And I want to finish looking that one up and incorporate the best advice =
from
there too (the testing section is nice, and the comments)
=20
BTW, it's missing the most important rule, that can turn the shell into=
a programming language: the -e option. Not using it is basically
equivalent to wrapping every python line within its own try-except-pass=
block.
-e option is useful yes, but not always so helpful, agree that in the bes=
t case
you should use it. But sometimes is not so simple and people end up writi=
ng '||
:' at the end of each command.
I planned on adding more about bash options to the wiki, and also some
debugging, but did not have the time. Point taken.
When I educate people I do this to allow people to contribute to any
pr=
oject.
In our case this will enable people to contribute to infra and
product.=
Having your own conventions to infra which are not following product st=
andard
will make it difficult to reuse people skills.
Let's write everything in javascript so we can all contribute to engine a=
nd is
the only language that can fit everywhere (ui included)... the goal of th=
e
product is different from the goal of infra, the tools should be the best=
suited
for the goals of the team, and if we can choose the same tools without lo=
osing
focus towards our goals then we should.
I'm not sure either of the percentage of shell scripts that are there in
product, but I'd say that it's not that much, as most of it are make scri=
pts and
relatives.
POSIX code is not less readable, one just need to accept that we follow=
standards and everything else will be aligned.
I don't agree, POSIX standard makes code a lot less readable if not using=
'extensions':
ssh -tNL 1234:127.0.0.1:4321=09
### Imaginary non-POSIX compliant ssh that uses GNU extensions
ssh --force-tty --no-command --local-tunnel 1234:127.0.0.1:4321
[[ "${myvar: -1}" =3D=3D "/" ]] ## the variable ends with
'/'
[ "$(printf "$myvar" | tail -c 1)" =3D "/" ] ## remember
that echo -n =
is not
posix compliant
do_something &>something.log
do_something 1>something.log 2>&1
Or any case where you have to go to sed/awk/python/ruby to get rid of the=
POSIX
restrictions and use their own programming languages. Having to understan=
d 2
languages to read a script is less readable than having to understand 1 i=
mo.
Having to expose all the variables as global is also less readable and a =
lot
more prone to errors too.
do_whatever() {
for i in one two; do
echo "inside i =3D $i"
done
}
for i in three four; do
do_whatever
echo "outside i =3D $i"
done
The output of that is:
inside i =3D one
inside i =3D two
outside i =3D two
inside i =3D one
inside i =3D two
outside i =3D two
The non-POSIX equivalent using local does what you expected:
do_whatever() {
local i
for i in one two; do
echo "inside i =3D $i"
done
}
for i in three four; do
do_whatever
echo "outside i =3D $i"
done
inside i =3D one
inside i =3D two
outside i =3D three
inside i =3D one
inside i =3D two
outside i =3D four
The fact that you expect the code to do something and it does something e=
lse
goes inside non readable to me (because it's not easy to understand what =
it does
reading it).
--=20
David Caro
Red Hat S.L.
Continuous Integration Engineer - EMEA ENG Virtualization R&D
Email: dcaro(a)redhat.com
Web:
www.redhat.com
RHT Global #: 82-62605
--JmDNeoq8Ebv1nqkSd8BNHALVJ2SuOPi93
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAEBAgAGBQJTBx7qAAoJEEBxx+HSYmnDqosIAJdf+y8kyrWisQVO0BoZRizA
aC3uAhFQ0j+XOHQ0MMmZ7jZG5uVEKf8A3OcqVsNJilNvwIYz7JIeyO2AiQ4w2PU0
8kavaZo2g4sHOTF7ctd20MS+vyGDd0nO8yXdaGCMakrjc5A+I8YMgrRePAJ4zoI1
9+rr3tcvhypRgK71eiRdXGko9ryAQqLA8rj3Nc4jg+AU17fL9YeVoeTe8gBMvfC6
pyoT9rHg0/Vqqud4ChTeMtxV9w21ivIliPuzg6kHPae32C2WxWelkStKu6436L6j
pvwG3sY27hkvn+hewh2edFiJITFMZOZiOAl+zR0M16tn+559uy9/dvJGx5MhUjw=
=TyBP
-----END PGP SIGNATURE-----
--JmDNeoq8Ebv1nqkSd8BNHALVJ2SuOPi93--