Bash scripting cheatsheet
devhints.io
devhints.io
Ruby and Python, meanwhile, are not quite so universally installed as Bash, and they have had all sorts of major breaking changes since 2004. And even if they are installed and version-compatible, they still might not work. Countless times have I seen a misconfiguration with Python 2 vs 3 or RVM or the PATH variable or whatever else cause errors, but I have never run into a scenario where a Bash script didn't just work.
All that said, I'm totally with you that Bash scripts should be short and sweet. If you're doing something with over 100 lines, Bash's downsides overtake its benefits.
Edit: I read your post quickly, you addressed the old bash scenario, but still in my opinion I would always, and do target POSIX shell for maximum cross-platform compatibility and that is definitely available on Unix-like OSs by default.
Python 2/3 was a pain, Ruby had very disparate versions available. But now, a few years later, you can assume at least Ruby 1.9 nearly everywhere, and OTOH still can’t use any of the Bash 4 features. There also quite decent cross-platform packaging solutions for python, ruby, node, go, crystal, mruby that make it really hard to choose bash for any serious project.
Perl/Ruby are too clever for me.
You should rather look for languages like fish, which makes shell scripting feel better than drop it altogether.
This cheatsheet is still a nice to have though.
This is true for the [ command, which is the same as `test`, but the [[ ]] syntax is parsed directly by bash, as is (( )). In particular, [[ ]] is not subject to whitespace splitting, so you don't need to quote most variables.
They mention $(( )), but don't go into (( )), which gives you very nice integer arithmetic and logic:
for (( x = 0; x < 5; x += 2 )); do
echo $x
(( y = x * 10, z = y + 2 ))
echo $y $z
done[ Is a Builtin, But [[ Is Part of the Language
http://www.oilshell.org/blog/2016/10/12.html
I didn't know that before I started implementing a shell :)
I knew that [ could be a builtin or /usr/bin/[, but not about the difference between [ and [[.
Using () instead of {} for the functions body allows to isolate it:
foo=5
bar() (
cd /
foo=7
)
bar
echo $PWD # not / but the current directory
echo $foo # still 5
Bash 4.0 can splat array of arguments back into a valid bash string with @Q. This is super useful when you need to stop using arrays, like with `bash -c` ary=("arg1" "arg 2")
echo "${ary[*]@Q}"
# outputs: 'arg1' 'arg 2'Cheatsheets are dense, well formatted items that either demonstrated a thing or reminded you of a thing. Ideally they would be printable in either letter or A4, possibly double-sided.
We need a different word for what this is. Tips/hints blog post?
brace expansions
combine for combinations
{a..c}{1..3} # a1 a2 a3 b1 b2 b3 c1 c2 c3
step size
{0..10..2} # 0 2 4 6 8 10
mapfile to read lines from file to array mapfile -t arrayname < filename
-t # remove trailing newline for each element
-u FD # read from file descriptor FD
-s N # skip first N lines
-n N # read at most N lines
-O N # start populating array at index N
array quoting "${array[@]}" # expand all elements, individually quoted
"${array[*]}" # expand all elements, group quoted
translate number from base to decimal for base in (2,64) $(( base#num ))Start by moving code into bash functions if it's not already doing that.
Declare variables with `local` to reduce the amount of global state.
Once you have code in functions, you can factor code into independent scripts. Anything that runs in a subshell can move into its own script, so anything:
1. in a pipe | line
2. running in the background&
3. in a ( subshell )
4. that doesn't modify global variables
You can then work on those scripts piece by piece.
Using shellcheck will give the developer more confidence in their code, and also learn through the feedback it gives
Maybe they meant `cat file.txt | while ...`? Even then, you never want to do that when you're reading because elements of a pipeline are run in subshells. The usual idiom is:
while cond; do
thing
done < input > output
It's also the problem with cheatsheets: the underlying idea in bash is that compound statements are like mini programs, so they have file handles that can be redirected. That doesn't come through a cheatsheet very well. If enabled, history expansion will be performed
unless an ! appearing in double quotes is escaped
using a backslash. Only backslash (\) and single quotes can quote the history expansion character.
where the newer man page says: Only backslash (\) and single quotes can quote the history expansion character,
but the history expansion character is also treated as quoted if it
immediately precedes the closing double quote in a double-quoted string.
Thanks for pointing this out!The thing is I actually find it quicker to simply use my own notes today and/or google anything I need to know when I need to know it.