My bad... Sorry for the mail format.
On 09/06/16 22:09, Antenore Gatta wrote: > Hi Evan! > > Thanks for this, it's something I can finally be involved (at least I hope). > > On 09/06/16 20:35, Evan Gates wrote: > >> Shebang: Use #!/bin/sh and only use POSIX shell features. If you need >> bash features use the proper shebang, either #!/path/to/bash or >> #!/usr/bin/env bash > I agree with Hiro, bourne is not bash and scripts should be written in > bourne > shell, not bash... Better, in clean, simple, old style, POSIX compliant > shell. > > So, just #/bin/sh > > Whatever there is behind is the OS business to make it works like full > POSIX shell. > > I write my personal scripts in bash >4.0 or zsh or ksh93, I write portable, > correct scripts in sh. > > From man sh: > > >> DESCRIPTION >> The sh utility is the standard command interpreter for the > system. The >> current version of sh is close to the IEEE Std 1003.1 (“POSIX.1”) >> specification for the shell. It only supports features designated by >> POSIX, plus a few Berkeley extensions. This man page is not > intended to >> be a tutorial nor a complete specification of the shell. > >> Extension: Do not give your script a .sh extension. An executable >> script is defining a new command. Do you run ls.elf? Furthermore if >> the script is later rewritten in a different language the extension is >> now wrong. It is acceptable to have a script with a .sh extension in a >> project as long as it is then stripped of the extension and made >> executable during the build (just like a .c file would be). The >> following rule already exists as a builtin inference rule in POSIX >> make to do this: >> >> .sh: >> cp $< $@ >> chmod a+x $@ > I'm not completely agree about this. > A shell script it's not an executable by itself, it's a plain text file, > like a > .c file. > > A script installed under /usr/bin (or whatever), yes, it'd be installed > without > extention, that's why you find often that make rule. > > Whan you take a look at a project knowing it's extention simplify > finding out > what that files are meant just looking at the extention. > >> Quoting: Quote all expansions/substitutions. e.g. always use "$foo" >> and never use $foo. There are an extremely small number of acceptable >> reasons to break this rule, e.g. $CFLAGS (note that some parts of the >> grammar do not require quotes for safe expansion such as assignment >> and case $var in, we should discuss what to require in these cases) > In my opinion just always. It doesn't make sense having exceptions. > > >> Storing Commands: Do not store commands in strings. This is what >> functions are for. Storing complex commands in strings and trying to >> execute or eval them is fragile and needlessly complex. >> >> Command Substitution: Always use "$()", never use backticks. This >> makes for easier nesting and fewer surprises. Remember these should >> always be quoted. > s/Storing Command/Substituting Commands/ > > I'm agree but I wouldn't fix a rule about this... Just prefer $() > > Remember to quote whatever is inside the the substitute commands and > that you can > nest them: > > $(whatever "$foo" $(othercmd "$bar")) > >> Variable Names: By convention all cap names are reserved for internal >> shell variables and environment variables. If your variable is not >> exported to the environment for use by a child process it should not >> be all caps. Lower case variables also greatly increase readability. > I would also initialize variables in the beginning of the > script/function, for > readibility. > >> Errexit: Do not use set -e. It is a legacy feature that is broken by >> design and includes many corner cases and gotchas. Check the result of >> each command that can fail and exit if necessary. >> >> Checking exit status: Do not run a command and then check against $?. >> This is pointless. Instead check the exit status directly with if >> cmd; then .... or by using a boolean operator such as cmd && ... >> >> Do not parse ls: ls is a tool to view files in a human readable >> format. Most often when someone tries to use the output of ls they >> really just wanted a glob anyway. >> >> Test: Do not use parens or boolean operators inside test expressions. >> They are deprecated and useless. Instead of [ "$a" = foo -a "$b" = bar >> ] use [ "$a" = foo ] && [ "$b" = bar ] >> >> Echo and printf: Do not use echo if your input includes a variable or >> backslash. There is no safe way to do so. Use printf and %s instead. > Regarding Hiro' comment, the argument against echo is that it's often a > shell > builtin, therefore it may sometimes behave in a strange way. > > This is sometimes true, but printf is not safe as well from that point > of view, > as it's a builtin as well in most shells. > > In a pure, POSIX, bourne shell implementation printf its the same as the > C printf > function, so it's preferred for formatted output. > > In scripts where you just need to output text, or to easily list files, > echo is > fine. > > echo * > echo /path/*/whatever/*sh # that is better and faster than "ls" > echo "I'm right" > >> These cover the most common mistakes I see. >> >> I would be happy to comb through suckless projects and submit patches >> that at least fix broken/dangerous code and preferably style aspects >> as well. > A flame maybe, what do you think about shellcheck? [1] > If it sucks (IMO it doesn't at all), do we need a suckless version. > > [1] http://www.shellcheck.net/ > > >