11 ms·
Something about functions in Bash (2017)
- llimllib 8y agoIf you rely on `(` instead of `{` to create a subshell and you don't comment the heck out of it, you are doing evil
- psetq 8y agoI was about to comment about how it took me several reads and then finally reading the "compound commands" section of `BASH(1)` to recognize the use of `(` vs `{` in the examples. That distinction should have been made clear in the example IMO.
- ben509 8y agoEven more fun: I was working on an unholy bash script that had a long curly brace block, and I was wondering why none of the environment variables survived. Then I noticed, tucked away at the end: ... kill --all humans touch $children fork yourself } | log Because, you see, components of a pipeline have to be run in subshells...
- yjftsjthsd-h 8y agoWhy? () is the obvious way to get an independent subshell. I guess it's annoying if you're not used to the distinction, but it's not hard. Is it really not common knowledge?
- llimllib 8y agoBecause it parses, visually, EXTREMELY similarly to `{` in a place where almost everybody who programs in a brace-y language will expect a brace. Thus most people will not notice it unless you point it out very explicitly, and it has the potential to cause great confusion.
- maxxxxx 8y agoI am always impressed how powerful and efficient shell scripts are but the syntax is just a killer. Is there a strong reason why all shells have this crazy syntax? Is it not possible to create a shell with a more expressive syntax like Java, C# or whatever?
- patrickmay 8y agoscsh (https://github.com/scheme/scsh https://github.com/scheme/scsh). Plus, it has the best Acknowledgements section of any technical documentation ever (https://scsh.net/docu/html/man.html https://scsh.net/docu/html/man.html).
- rashkov 8y agoWas glad to look up his CV and see that he's still around.. I'm not sure that 90s grumpy nerd humor has aged well into 2018, but I do appreciate the throwback to a different time
- psetq 8y agoAlternatively, Is there any reason today to not just use a language like Python/Ruby/JS for where shell languages would have been used?
- reificator 8y agoNumber one reason is availability. Do all of your current and future targets have the right version of Ruby installed? What if you have a mix of python 2.7 and 3.6?
- sethrin 8y agoI'm strongly considering making it a point to do just that: include Ruby in all the images I can, just to not have to use Bash. For one-liners it's fine, but I don't get ten lines into a Bash script before missing scripting-language features. However, if someone were to try to talk me out of what they consider to be an absurd notion, I would be prepared to take their criticism seriously.
- pas 8y ago> Not only do these tricks make your code nicer [...] Huh.
- zzzeek 8y agofor context, author of blog post has written two published Perl books. To make matters worse, they are called "Perl One Liners", "Perl One Liners Explained".
- deleted 8y ago[deleted]
- bewuethr 8y agoTo clarify: "Perl One-Liners Explained" is self-published, and "Perl One-Liners" is based on it and published by No Starch Press. Not sure why that makes "matters worse"? He also self-published "Awk One-Liners Explained" and "Sed One-Liners Explained" and has a "Bash One-Liners Explained" in the pipeline, see http://www.catonmat.net/books http://www.catonmat.net/books
- psetq 8y agoCuriously, the article was published on April 1st. Just a coincidence perhaps...
- jschwartzi 8y agoI have a similar knee-jerk reaction to one-liners from a maintainability standpoint. I have this mental vision of Perl or Shell that looks like Brainfuck.
- HerrMonnezza 8y agoNitpick: although the linked page states that defining functions as compund commands is a `bash` feature, it is actually in the POSIX `sh` standard [1] so it should work with any POSIX-compliant shell. [1]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3... That said, I'm curious what are the nifty tricks that one can do by using functions as "aliases" for compound commands -- I cannot see much of a difference between `function sleep1 () { while true; do "$@"; sleep 1; done; }` and the similar definition without the curly braces. Only once in my life I have had to use the `function foo () ( ... )` syntax (i.e., using subshell instead of normal `{ ... }` grouping).
- schoen 8y agoI'm always amazed at how many Unix features I assume are GNUisms or bashisms that turn out to be in POSIX and be much more portable than I've expected!
- webreac 8y agoI'm always amazed at how scripts intented to use only POSIX features become buggy when dash is used instead of bash.
- yjftsjthsd-h 8y agoYeah, for anything that I want to be portable, I explicitly run it with bash, dash, mksh, and heirloom sh. I figure that if it works in all of those, then the result is either truly portable... or nobody will ever notice:) It also should really help that Debian, IIRC, actually sets /bin/sh to dash by default?
- frou_dh 8y agoFor those who've never looked at the POSIX docs, bookmark this: http://shellhaters.org http://shellhaters.org ...which is a great jumping off point to casually read a bit of them now and again.
- 8y ago
- KeyboardFire 8y agoHmm, why doesn't `fn() echo test; fn` work? It seems to work in zsh, but not bash.
- HerrMonnezza 8y agoBecause `echo test` is not a compound command. Informally, a compound command is a list of commands (`( ... )` or `{ ... }`) or a looping or conditional construct. See [1] for a precise definition. [1]: https://tiswww.case.edu/php/chet/bash/bashref.html#Compound-Commands https://tiswww.case.edu/php/chet/bash/bashref.html#Compound-...
- inetknght 8y agoIf you get bored with basic shell commands, I highly recommend learning what GNU coreutils provide. I never would have loved Linux without this installed. https://www.gnu.org/software/coreutils/manual/html_node/index.html https://www.gnu.org/software/coreutils/manual/html_node/inde...
- derekp7 8y agoSomething else you can do with BASH functions is use: declare -f function_name to print out the contents of a function, in a format that can be directly evaluated with command substitution. This is useful if you want to send a function (or a number of functions) into another BASH instance (such as via an SSH connection). A google search for "RPC in Bash" will take you to a GIST I put up on Github a while back that gives details of how this works. You can do this in ksh93 also, I believe you use typeset -f instead of declare -f.
- jodrellblank 8y agoYou can do this in PowerShell also: get-content function:function_name `function:` being a filesystem-like PS Provider.
- lsiebert 8y agoJust a note that defining a function using the keyword "function" is a BASHism, not generalizable to every POSIX-compliant shell. In BASH, as well as any POSIX shell, you can define a function with function_name () and just remove the "function" from the front. one of the many things I learned by using Shellcheck for static analysis https://github.com/koalaman/shellcheck https://github.com/koalaman/shellcheck
- kps 8y ago“function” was borrowed from ksh (like many other ‘bash’ features) but with gratuitously incompatibilities (like many other bash ‘features’).
- badloginagain 8y agoShellcheck is one of those rare tools that made me a significantly better developer. In part because the more bash a dev knows the more effective they are at life in general, in part because it made it easy to follow rigorous coding standards- allowing me to take the quality-code mindset to less rigorous environments.
- sethrin 8y agoI wrote a short book for novices on shell usage, because it is extremely important for developers to know. Bash one-liners are usually even pretty defensible. But I dream about how the world would be if Bash were actually a good scripting language. It compares favorably to csh, and I fear that's about the best you can say for it.
- AceJohnny2 8y ago> But I dream about how the world would be if Bash were actually a good scripting language. It compares favorably to csh, and I fear that's about the best you can say for it. I finally started appreciating Perl after having to write some nontrivial Bash scripts. (My hierarchy is: default to Bash when my task is mostly running commands. If there's a bit of text-processing or regex required, Perl. If I need any hierarchical datastructures, Python)
- redcat255 8y agoThis seems like a good place to ask. I've been putting off properly learning bash (instead of googling for basic structures whenever I need to write a script) for quite a while now, what resources do you recommend for doing so?