4 ms·
I do quite a bit of programming in bash. One construct in bash is absolutely super: process substitution. You can read the output of a program as if it were a f
by gizi 11y ago
I do quite a bit of programming in bash. One construct in bash is absolutely super: process substitution. You can read the output of a program as if it were a file with the construct: <(myprogram).
Bash is a fine tool, but it has a number of flaws that prevent me from using it for certain tasks.
* Functions can only return a status number. Functions are always subshells.
* The hashtable (associative array) syntax is unpalatable, unreadable, and a real abomination. I simply don't use it, because it gives me a headache.
* I can never remember the horrible syntax for most string functions.
* You cannot reasonably store an arbitrary json structure in memory. Embedded lists and hashtables are absolutely unwieldy.
* Bash has no concept of FFI (Foreign-function interface). So, you cannot load an external library and invoke functions it it.
These problems are not particularly impossible to solve, but the Bash authors will probably never do it. Therefore, the final reproach against bash is that they do not publish their source code in an environment similar to github, where users can file their issues and improvement requests. In other words, the bash authors are not in communion with their users.
In what way can the fish shell address these problems?
- e12e 11y ago> One construct in bash is absolutely super: process substitution. You can read the output of a program as if it were a file with the construct: <(myprogram) Actually had to look that one up[1] -- unfortunately you're right, it's not posix (I don't think I would've tried it in a [ed: non-interactive] script, but I agree it is very nice). I wonder if you could make a function as a work-around, something like: r() { #r(first some args <(second other args)) # Use a fifo: ff=$(mktemp fifo) # might as well use that for parsing the commands... echo "$*" > $ff first=`sed -re 's/\((.*) <\(.*/\1/p' < ${ff}` echo "$*" > $ff second=`sed -re 's/\(.* <\((.*)\)/\1/p' < ${ff}` ${second} > $ff & ${first} < $ff } Adjust for parsing the direction of the <() vs >() etc... Not particularly robust, and the above is un-tested... Just an idea. I'm not convinced trying to parse shell command lines for macro functionality is a good idea in general... [1] http://mywiki.wooledge.org/Bashism http://mywiki.wooledge.org/Bashism
- unhammer 11y agoApparantly it's built-in as psub for the <() case (I was looking for the same thing https://news.ycombinator.com/item?id=9569730 https://news.ycombinator.com/item?id=9569730 ), not sure about >()
- e12e 11y agoIndeed. Came across this: http://arstechnica.com/information-technology/2005/12/linux-20051218/4/ http://arstechnica.com/information-technology/2005/12/linux-... I hadn't really thought about that echo'ing the filename might be useful, but this is pretty equivalent to how things work in bash -- with "diff <(some) <(other)", diff gets two temporary file-handles to two fifos -- that are later cleaned up by the shell. As most good ideas, obvious when you think about it :-)
- rlpb 11y ago> * Functions can only return a status number. [In Bourne shell] A function can just print to stdout, and the caller can capture it. In this way, a function has two outputs: an exit status, and a (normally text) result. It's unusual to go any further, but if you really wanted to you could make a function return any number of outputs by writing to different file descriptors and having the caller capture them all separately.