Live data from Hacker News

Ask HN: How can I get better at bash?

news.ycombinator.com

161–170 of 195 posts

Re: Ask HN: How can I get better at bash?

#161

If you're not already familiar with it, I would suggest learning about the basic Unix process model -- fork, execve, wait, open, pipe, dup2 and friends. Bash is essentially a DSL for these. A lot of the weirdness you see in the language is due to these abstractions leaking through. For example: * Quoting is building execve's argv parameter. It's hard to quote correctly if you don't know what exactly you're working to…

> Quoting is building execve's argv parameter.

can you expand on this? does this elucidate, e.g., variable substitution and the difference between single- and double-quotes? or does it just help demonstrate when you need quotes for an argument that may contain whitespace?

Re: Ask HN: How can I get better at bash?

#162
post #55

Earlier quoted context omitted.

> Like iterating over the files in a directory, for example. If you think that's easy in Bash you have either have a funny definition of easy Maybe I'm overlooking something...but why wouldn't this work: for file in $(ls); do { }; done

$ mkdir "hi there" $ mkdir "how are you" $ ls -l total 8 drwxr-xr-x 2 xxxxxxxx xxxx 4096 Jun 26 14:54 hi there drwxr-xr-x 2 xxxxxxxx xxxx 4096 Jun 26 14:54 how are you $ for f in $(ls); do echo $f; done hi there how are you

Fair enough.

Re: Ask HN: How can I get better at bash?

#163

Earlier quoted context omitted.

$ mkdir "hi there" $ mkdir "how are you" $ ls -l total 8 drwxr-xr-x 2 xxxxxxxx xxxx 4096 Jun 26 14:54 hi there drwxr-xr-x 2 xxxxxxxx xxxx 4096 Jun 26 14:54 how are you $ for f in $(ls); do echo $f; done hi there how are you

ls | while read file; do echo "$file"; done ... works better for the easy edge cases, but still probably has some issues. Personally I think klodolph called it; once you get into anything that has a few interesting edge cases bash becomes pretty unwieldy.

The easiest way is still: for file in *; do ...; done

This works fine with spaces and other strange characters, no need to come up with more complicated ways.

If you must use find, the correct way is really tricky and uses obscure bash features like settings IFS to the empty string to split on null bytes and process substitution so that the loop doesn't run in a subshell (which would prevent it from modifying variables in the current environment):

while IFS= read -r -d '' file; do ... done See http://mywiki.wooledge.org/BashFAQ/020

Re: Ask HN: How can I get better at bash?

#164
post #155

Earlier quoted context omitted.

What is a good learning resource for what the basic Unix process model (i.e. what you are describing?) Do you recommend a book or something like that? And preferably for a beginner?

Stevens - Advanced Programming in the Unix Environment Love - Linux System Programming The Unix-Haters Handbook (Unfortunately, the best resource ever for this kind of stuff, from which I learned, does not have an English translation.)

What resource was that?

Re: Ask HN: How can I get better at bash?

#165
If you're interested in getting better at the terminal, I recommend you learn how to customize it. it'll really help you learn by doing and figuring out what it is you want to learn how to do first.

It's what worked for me, though. There are also some workflow ideas that have really helped a lot. Autocompletion and being about to look through your history for commands is super helpful too.

``` cat $HOME/.bash_history | grep -E 'command|argument' ```

https://github.com/zsh-users/zsh-autosuggestions

I just finished a guid on my site about my terminal setup. I hope to read yours once you've customized the pixels out of it.

Aside from things to get your interested in the internals of your shell via bash scripting, you should also consider writing more shell scripts specifically around your workflows. I keep mine in a .files repo on GitHub. Take a look at the install script. It took me over a year to get really fluent in bash scripting enough to make it possible to get better and better at it.

Good luck on your journey!

Re: Ask HN: How can I get better at bash?

#166
man bash. read, digest, apply, repeat. you can also look at existing scripts, figure out what they do, why, make copy, alter, see the changes in behavior. there are also books on bash.

larger point: how do you learn more about X? or get better at doing X? figure that general pattern out and you can re-apply it for anything, not just bash.

Re: Ask HN: How can I get better at bash?

#167

From a 14+ year Linux/Unix admin: Get a very brief reference book of every common UNIX command. Read all the commands, what they do, what options they take. Start using them. Shells are most useful when they are used to tie together other programs. In order to do this, you have to know what all the command-line tools you have at your disposal are. Learn the tools, then start writing examples using them. Keep the exam…

"(and 'links -g' provides a graphical browser if you need images)" Without X presumably needs framebuffer or something?

It has a variety of drivers, such as for X, framebuffer, svgalib, OS/2 PMShell and AtheOS. It also bundles antialiased fonts.

Re: Ask HN: How can I get better at bash?

#168

If you're not already familiar with it, I would suggest learning about the basic Unix process model -- fork, execve, wait, open, pipe, dup2 and friends. Bash is essentially a DSL for these. A lot of the weirdness you see in the language is due to these abstractions leaking through. For example: * Quoting is building execve's argv parameter. It's hard to quote correctly if you don't know what exactly you're working to…

> Quoting is building execve's argv parameter. can you expand on this? does this elucidate, e.g., variable substitution and the difference between single- and double-quotes? or does it just help demonstrate when you need quotes for an argument that may contain whitespace?

The behavior of quotes can and should be described in terms of how they affect the words they expand to (i.e. the argv you build), so yes, it clarifies all this.

For example, all the various wrong ways of quoting var="My File.txt" or otherwise incorrectly using such a name will result in variations on a wrong argument list:

  execlp("cat", "$var", NULL);            // cat '$var'
  execlp("cat", "My", "File.txt", NULL);  // cat $var
  execlp("cat My File.txt", NULL);        // cmd="cat $var"; "$cmd"
  execlp("cat", "'My", "File.txt'", NULL);// cmd="cat '$var'"; $cmd
  execlp("cat", "My\\", "File.txt", NULL);// cmd="cat My\ File.txt"; $cmd
  execlp("cat", "'My File.txt'", NULL);   // var="'$var'"; cat "$var"
  execlp("cat", "\"$var\"", NULL);        // arg='"$var"'; cat $arg

Meanwhile, all the correct ones result in the same, correct argv:

  execlp("cat", "My File.txt", NULL);  // cat "$var"
  execlp("cat", "My File.txt", NULL);  // cat 'My File.txt'
  execlp("cat", "My File.txt", NULL);  // cat "My File.txt"
  execlp("cat", "My File.txt", NULL);  // cat My\ File.txt
  execlp("cat", "My File.txt", NULL);  // cmd=("cat" "$var"); "${cmd[@]}"
  execlp("cat", "My File.txt", NULL);  // arg="'My File.txt'"; eval "cat $arg"
If you don't know which argument list you're aiming for, you basically have to go by guesswork and superstitions.

Re: Ask HN: How can I get better at bash?

#170
post #58
post #13

How about you don't? Bash as scripting language is rather mediocre. Anything that is not simple in bash gets hard to read and debug and probably is wrong on some subtle levels. I have a rule of thumb that any shell script that grows beyond a screenful of lines gets redone in a proper scripting language.

Totally agree. Also, even if you manage to become better in Bash, you are bound to lose your skills at some point when you have been programming in other languages for a while. I always have to look up how to do even basic things in Bash. I just don't use it often enough for these things to "stick".

It's okay to not have everything memorized. As long as you know what to look for, you're only a google search away.
Post reply on HN