Hacker News new | past | comments | ask | show | jobs | submit login

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 towards.

* Redirections are opening and copying file descriptors. It explains their scope, order and nesting behavior.

* Variables are modifying and passing the environment, and their weird scope is due to forks imposed by the process model.

Once you know how you can do whatever you want in C through the basic syscalls, Bash is an extremely efficient and far less surprising shortcut to do it.




> 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.


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?


The notes by my OS lab professor, written in Romanian, with self-learning in mind, with detailed explanations of the workings of major system calls and featuring numerous working examples and pitfalls.

I might translate them some day and put them up on the Internet (if I get his permission and some free time).


Thanks man.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: