107 comments

[ 2.9 ms ] story [ 177 ms ] thread
(comment deleted)
Seems like everything after 'Variables and Expansion' isn't finished yet, hence the emptyness.
(comment deleted)
this is, for the most part, non-functional and incomplete
please test the site before releasing it.
Folks, it's most likely the case that the author behind bash.academy did not post the link to HN, so ease up on the flames.

I for one am enjoying reading through the informative guide.

Nice job on the author for deploying Prose.io for community editing of the guide.

(comment deleted)
> Get off your high horse.

The irony.

It's entirely possible to learn improper bash when cobbling stuff together over the years. I've certainly done a few things that I've since found much better alternatives for.
Oh come on! It is clear that English is not his first language. Give him a break.
As opposed to improper bash? Get off your high horse.

There is very much a bad way of doing bash. When I first started doing bash scripts, most of them looked like this:

cat file | grep string

cat file | wc

cat file | while read line

Multiple problems there. Then there was my initial attempts at finding files in a directory:

for i in `ls *`

This is when I learned about globbing.

There is enough variance in how things can be done in Bash with varying degrees of effectiveness that Google even has a Shell Style Guide: https://google.github.io/styleguide/shell.xml

Thanks for the link to the Google Bash Style Guide. A good read.
We all get tricked by the "useless use of cat" thing occasionally :)
I'm not so sure it is so useless. Consider when you want to "grep something access.log". Then you want to look at yesterday's so it's "grep something access.log.1". Then you want to look at the log before that, but it's compressed. "gunzip -c access.log.2.gz | grep something". (Ignore zgrep for the moment. Let's say I want to use grep's -A and -B options to show context of the lines that it finds.) To switch between the compressed and uncompressed files, you have to move the filename to a completely different part of the command, which requires more re-typing. You would have been better off starting with so-called "useless" cat. Separate out the concern of "putting a stream into the pipe" from "doing something with the stream". gunzip -c is just one command that might produce output.
This is a WIP (hence why there are drafts and todos). This is being done by the folks at http://mywiki.wooledge.org/BashGuide which is definitely a valuable resource if you're trying to learn Bash and its idiosyncrasies.

Another good resource is http://wiki.bash-hackers.org/.

I find the idea of a bash academy somehow absurd, but if it's done by the guys from greg's wiki then it's alright.
^^^ This! Greycat's bash guide is the definitive guide as far as I'm concerned. If this project is being done by them, I'm behind it.
Looking at the github page https://github.com/lhunath/bash.academy Its been there for 2 years. and last commit was 3 months back.
Omg a whole 3 months ago???!! This repo is soooooooo stale. Bash is constantly changing every day right? I don't want to learn from an antiquated resource!
I posted above stat as response to someone telling the link is posted in HN while the project is still in its early stage. (work-in-progress).
remember, kids: duration of time is the sole data point with which you should determine what "stage" a project is at.
Yes kids remember, if a project more than 2 years, don't say things like "You posted the link, while author just getting started."
This is much needed. We essentially have all this software we deal with daily and many people don't know basic things about it, not just bash or zsh... and that is funny, people install zsh because it's the thing to do, but you see that they don't know why.
(comment deleted)
Thanks for making this! I wish I had a guide like this when I was starting out. Does anyone know if there is something like this for zsh? I'd imagine there would be a lot of similarities, but some notable differences.
I know this is still a WIP, but I found the examples tough to read with colors chosen. Should add does look like a fantastic resource though!
If you are writing functions in Bash, your task is probably sufficiently complex that it would benefit from being written in a language other than Bash.
Please list other backwards-compatible interpreted languages installed by default on dozens of operating systems and platforms spanning 26 years.
Awk and perl.

I use a lot of bash though.

About 7 years ago I had a job where we supported almost every Unix all the way back to AT&T SVR3 (including OpenServer, UnixWare, HP-UX, AIX, Linux, OSF/1). With the exception of SVR3 every single one had binary packages for Perl 5.
until you run embedded routers and such, where perl is too large and bash/ash/mush rules.
Or you're bootstrapping an install process and perl isn't included, but a shell is.
Perl, it's everywhere, and is a better bash than bash is.
(comment deleted)
Hint: it's not Bash. That would be sh, which is not really portable--if it were, autoconf wouldn't spend so much effort on portability.

So yes, can anyone provide such a list please?

Actually, this is exactly the sort of guide I've been meaning to read, since I'm inclined to take the opposite view.

Too often, I think, my task is probably sufficiently simple that it could be a nice portable obviously-a-script Bash script rather than Python/whatever.

Agreed. Bash (and similar scripts) are particularly useful in tasks involving filesystem and process management, where they offer capabilities that are more complicated in other languages. Functions are a helpful way to organize your use of those capabilities.
Possibly, but bash functions can still be quite useful even in a relatively simple script.
It's useful to be able to write functions for your shell. For example, I have a function up, which moves up n dirs.
I wrote this function for my .bashrc as soon as I read this.
I use pup a lot too, which just prints the dir.
Zsh has quite a nice option "auto_cd". If the first word you type doesn't resolve to a command, it tries to change the current working directory to it instead. So just typing ~ will get you to $HOME, and .. will take you up one.

    alias '..=cd ..'
    alias '~=cd "$HOME"'
Yes. Although you get it for free with Zsh where it works with any directory you type. Not just the ones you think to make an alias for beforehand. :-)
At one point I had ".." aliased to one directory up, "..." to two, and so forth. For navigating I found that preferable to cd ../../.. etc.
I love this option. I type "/tmp" when I'm about to create some short-lived scratch files. Those saying "you can just alias that" are missing the point. Where do you stop with the aliases?
(defun eshell/up (n) (dotimes (i n) (cd "..")))
(comment deleted)
(comment deleted)
Even if that is true, it doesn't mean you should not cleanup and organize the bash you have "today" and will port "tomorrow". In the meantime your bash will be better organized and more maintainable.
I wrote sh for this very reason http://amoffat.github.io/sh/ This lets you use a programming language, instead of a shell language, to solve programming tasks.
Bash functions are very useful when you want to manipulate the state of the shell in some way. That is, you write a function for it and stick that function in your .bash_profile. (Unless ofc an alias would be able to perform the job in which case one should just make an alias instead.)

Beyond that, I have been in many situations where standalone shell scripts make the most sense for a task and in which case bash functions have helped me organize the code such that it is both more readable and also so that I don't have to repeat sections of code multiple times within a single script.

It all comes down to personal experience and preference, I think.

Your point is valid, that bash should be avoided as processes become increasingly complex. But there is still room for bash. How much room depends on what you are trying to do.
Build scripts for various things are often done in bash, and functions are quite helpful there (unified cleanup routine, for example).

Just because you can do something in <pet-language-name-here>, doesn't mean it's best done in <pet-language-name-here>.

Bash is incredibly useful, and I think more people should use it as a cross-platform default scripting language. That said, for the most compatible shell scripting, learn Bourne shell scripting. https://en.wikipedia.org/wiki/Bourne_shell
It drives me nuts when people say this. /bin/sh is not even Bourne in some distros (dash in Debian for instance), and bash is installed everywhere (unless you're running AIX, I think ksh is still default). There are some bash-isms that are good things and people shouldn't be afraid of. I think it is actually counter productive to tell people to write things in other languages if you need more complexity. If you're writing a script I think you should be weighing instead whether or not you should fully automate what you're doing. If you decide that's the case of course bash isn't going to be your go-to tool, but if you're writing a one-off script what's the point of telling people to use a more robust language if you can do the job with bash?

I don't understand why people are so opposed to bash in general when it's so powerful for how straightforward it is.

Dash is Bourne-compatible! And Bash is not installed everywhere. I can think of at least five systems i've used in the past five years that either didn't have Bash, or Bash was not the default shell, and even the path to Bash isn't the same on all systems (since it is technically an add-on). Anyway, I did not say use Bourne for more complexity, I said for more compatibility.

People are opposed to learning yet another tool. But here's the really funny thing about the "use a more robust language" argument: not only do they introduce more dependencies, they can introduce more bugs (due to increased complexity), and are almost always a maintenance headache. The one thing that's easy to maintain after 10 years is a shell script. Perl is a nightmare to maintain after 10 years (mostly due to the lack of good Perl programmers) and awk is just barely better.

Right I was thinking about that after I replied to your comment, that I let my point get away from me. I read so many other comments putting down bash I was pleading my case to them, not you, haha.

I did not realize dash was bourne compatible. Also, I'm curious what systems you've used didn't have bash installed by default, as I haven't used anything in a long long time that didn't have bash.

Solaris, BSD, HPUX, hell even stripped-down Linux installs (though sometimes it exists and is just in a weird path). Occasionally I need to bootstrap an OS installer and they never have Bash.

By default I write Bourne, and if I need the extra complexity/speed/etc i'll switch to Bash, but it's pretty rare that I need to use Bashisms.

Something else to consider is that many embedded Linux systems do not have bash, only sh (aka Bourne shell). It is often easier to use only Bourne shell-isms to get things to work in a cross-target fashion. That said, I prefer bash for most cross platform (as in cross OS platform) tasks that need a simple shell script of some kind.
I've started trying to stick to dash syntax for shell scripts.
Does dash have some advantage to bash, except being faster? Doesn't it lack some useful bash functionality?
The main advantage is that it's a smaller dependency. If you don't need the functionality, there's a bigger benefit to being portable. For example, running scripts on a router with embedded linux.
The first few chapters look very good, best of luck with the rest!

In case anyone here is interested in more reading material, I recently wrote a small book about Bash that could be helpful: https://gumroad.com/l/datascience

To make sure it didn't read like a manual, each chapter is an "adventure", where I show how to use only command line tools to answer questions such as: What's the average tip of a NYC cab driver? Is there a correlation between a country's GDP and life expectancy? etc

After clicking the link to your book in Firefox, it is impossible to hit the back button to return to this page.
That's really strange; it might be an issue with Gumroad, sorry about that.
Works for me in chrome.
(comment deleted)
http://guide.bash.academy/03.variables.html#toc7 in this page those block-diagram looks nice, how is it made? some markdown enhancements like mermaid of plantUML?
(comment deleted)
We need the zshell academy
The site is unusable for me because of lag from the parallax. It's always on.
In hopes that the creator does read this, it looks like a great resource but I can't read the text, my eyes are very strained and I got a headache very quickly.