I would generally describe a GNU/Linux distro as being a "giant pile of shell scripts". That's a little less true with init scripts generally now being systemd units. But that's where I'd start: Look at the code that distros write, that isn't part of some other upstream software.
- Arch Linux's `makepkg` https://git.archlinux.org/pacman.git
- Arch Linux's `mkinitcpio` https://git.archlinux.org/mkinitcpio.git/
- Arch Linux's `netctl` https://git.archlinux.org/netctl.git/
- Downstream from Arch, Parabola's "libretools" dev tools package https://git.parabola.nu/packages/libretools.git/ (disclaimer: I'm the maintainer of libretools)
Gentoo also has a lot of good shell scripting to look a, but it's mostly either POSIX shell, or targets older Bash (their guidelines http://devmanual.gentoo.org/tools-reference/bash/index.html say to avoid Bash 3 features). I tend to believe that changes made to the Bash language over the years are enhancements, and that they let you write cleaner, more robust code.
Read it! It's great. But know that a lot of bash scripting isn't really in bash, it's really required to be proficient with grep, sed, cut, dc and a few other text processing utilities. Learn those! Then are are a few other tricks to be mindful of: be mindful of spaces (wrap your variable substitution in double quotes, mostly), be mindful of sub-shells (piping to something that sets variables can be problematic), and a few other things that can really only be learned by reading good code.
But it's also good to know when you shouldn't venture further. My rule of thumb is when I'm using arrays or hash maps, then it's a good idea to move to another language. That's probably Python nowaways. A lot of people use tons of awk or perl snippets inside their bash scripts, that can also be a sign that it's time to move the whole script over.
If you have more logic than a couple of string comparisons, Bash is not the right tool for the job.
Like others say, "bash" is a hard tool to get right (and I'm not saying I do it right either, necessarily, but Greg's Wiki was real helpful!). I'm building a hybrid bash/python3 environment now (something I'll hopefully open-source at some point), and bash is just the "glue" to get things set up so most aspects of development can funnel through to python3 + other tools.
But ... things that make bash real useful:
* it's available everywhere (even in Windows with Ubuntu-18.04/WSL subsystem)
* it can bootstrap everything else you need
* it can wrap, in bash functions, aliases, and "variables" (parameters), the
real functionality you want to expose ... the
guts can be written in python3 or other tools
Without a good bash bootstrap script you end up writing 10 pages of arcane directions for multiple platforms telling people to download 10 packages and 4 pieces of software per platform, and nobody will have consistent reproducible environments.EDIT: I think there's a revised version of Greg's Bash Wiki in the works.
Python, sure, but replacing Bash with Node just seems like replacing a language crippled by its need to be backward compatible with (Bourne) sh with a language crippled by its need to be backward compatible with what Brandon Eich came up with in two weeks in 1995.
Python is the more direct substitute, though: it's built-in to almost every platform, and the Python 3 stagnation has even given us a consistent version: 2.7.
You're forgetting that bash really just calls other code. So you can combine two language's stdin/out functionality (eg, Python or Node) to pair code together. Sure, it won't be fast, but it can do quick wonders as an ad hoc data pipeline.
Keep them short. There are always exceptions but the "do one thing" mantra is handy, they can always be wrapped into a more complex workflow with a bigger script. None of my frequently used ones are over 100 LoC.
Write them for you and you alone when possible, start off simple and iterate. Fight that developer urge to solve a generalized problem for everyone.
Embrace the environment and global environment variables. We're trained to avoid global variables like the plague but they are really useful in scripts. My auto complete scripts that I mentioned above, they know which database to connect to based off the environment variable and there are separate commands to switch environment.
Make sure you aren't using it where things like make would be more appropriate.
* use traps http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.htm...
* read about safe ways to do things in bash https://github.com/anordal/shellharden/blob/master/how_to_do...
* this is pretty helpful writeup of general CLI usage, yet not bash specific https://github.com/jlevy/the-art-of-command-line (related HN discussion https://news.ycombinator.com/item?id=9720813)
https://tiswww.case.edu/php/chet/readline/readline.html#SEC1...
Readline is the library bash uses for editing the input line, and it has some nice movement keys. For example Alt-b moves the cursor back a word, Ctrl-u deletes to the beginning of the line, Ctrl-w removes one word behind the cursor.
They work in a bunch of other programs, like the Python interpreter's interactive mode for example.
Often, this is a good sign that you might want to switch to another scripting language.
also, https://www.shellcheck.net/ not reading, but pretty neat. static code analysis for shell scripts, points out common errors.
I would highly recommend BashGuide[2] and ryanstutorials[3] as a starting point. After that, go through rest of the wooledge site for FAQs, best practices, etc
shellcheck[4] is awesome for checking your scripts for potential downfalls and issues
[1] https://github.com/learnbyexample/scripting_course/blob/mast...
[2] https://mywiki.wooledge.org/BashGuide
Why is that? Why don’t they build both from a single source?
This is the theory. The practice is that GNU mandates Texinfo for its projects, and because documentation tends to be the weak spot for all open source projects, manpages end up the most neglected as a result, which can be quite annoying. Especially since pretty much nobody else uses Texinfo - man pages are good enough for most console apps, and those that need more detailed documentation use Docbook, Markdown etc.
Typically (unless this changed at some point) the info pages are the canonical reference for GNU projects and the man pages are to accommodate Unix hackers.[1]
[1] https://www.gnu.org/prep/standards/standards.html#Man-Pages