Live data from Hacker News

Things I Wish I'd Known About Bash

zwischenzugs.com

141–150 of 272 posts

Re: Things I Wish I'd Known About Bash

#141

Earlier quoted context omitted.

While process substitution is great on the surface, it comes with a troubling downside: There is no way, that I have found, to reliably catch errors. That is, this: some-command ...will succeed. And -e and pipefail do nothing here. I have not found any way to push the error up. Plenty of questions on Stackoverflow and elsewhere, no good answers.

pipefail do nothing here Isn't that because the syntax provided doesn't use a pipe? Which is why actually using a pipe, rather than paren redirection, is easier on the eyes and the shell. It reads more like the flow of text: maybe_failing() { if ! some-failing-command; then echo "That did not shake out" >&2 return 1 fi } maybe_failing | some-command Is that one of the things StackOverflow said? And if so, why is it n…

This requires that some-command takes input from stdin (many commands don't) and that there's only a single input. What about:

  process-stuff --file 
This is the point at which one reaches for tempfiles, usually.

The point remains that Edit: Isn't substitution using pipes, though? As in FIFO pipes? You get a file descriptor device which is closed at the end of the script. I don't know if the fd is wired directly to the command's stdout or whether the output is written in its entirety to a hidden tempfile first; the former sounds more natural and efficient.

Re: Things I Wish I'd Known About Bash

#142
post #84

Earlier quoted context omitted.

If foo has a Texinfo manual (GNU tools like bash usually do) then you can try `info foo` and search the index with i or I for -p. Texinfo manuals also have hyperlinks you can press enter on. info is a greatly underused system and I'd recommend any *nix users to spend some time learning how to navigate it.

For bash: 'i' gives me "no indices found" and 'I' says "no index". I can do a '/' search, which finds some "-p" strings, but "n" doesn't work to find the next. From some other comments, it sounds like "info" uses emacs at its core? So I suppose I'd have to learn some emacs commands, if that's the case.

info works without emacs, but some people prefer emacs' info viewer to the console one. The console viewer does have some idiosyncratic keybindings - for example, "n" means "next node at same level", and "}" means "search for next occurrence". "H" will give you a quick overview.

I'm surprised indexes aren't working for you - unfortunately I don't know of any suggestions to fix that.

Re: Things I Wish I'd Known About Bash

#143

Earlier quoted context omitted.

The machine may not be ancient but I would still argue that the problem there is the ~10 year old version of Bash that Apple has decided to ship rather than the programmers that use features added to the shell within the last 10 years. (I should add that I don't know what version High Sierra ships with but Sierra seemed to ship with 3.2.5x-ish which was 9 years old at the time.)

Well put it this way: You can assume everyone has a modern bash, and make it the end users problem if they don't, or you can write portable shell scripts and know it will work. Honestly the things you can't do in posix shell compared to bash border on "use a fully featured language" anyway.

How do you write a portable shell script? The programs invoked by your shell script need to behave the same everywhere. Even fundamental things like cp, rm, etc. don’t universally behave the same across the various Unix and Unix-like systems.

The joke is that your shell is actually more portable than your shell script :)

Re: Things I Wish I'd Known About Bash

#144
post #125
post #116

$ grep somestring file1 > /tmp/a $ grep somestring file2 > /tmp/b $ diff /tmp/a /tmp/b You shouldn't do that, but not because it's not neat enough. /tmp is world-writable, so you might be writing to somebody else's file, or over a symlink that was set up by someone else. Use mktemp¹ for creating temporary files. ¹ http://man7.org/linux/man-pages/man1/mktemp.1.html

Could you not do that with pipes instead, something like: $ diff

That's what the article is recommending.

Re: Things I Wish I'd Known About Bash

#145
post #123
post #112

Earlier quoted context omitted.

In general, the best way to read Info documentation is inside Emacs.

"If you are a bash newbie, you should read the bash manual. If you want proper search for the manual, you should use info. If you want proper use of info, you should use Emacs." Kind of a deep rabbit hole, isn't it?

Not in this case; the bash manual is not in Info form, but a regular old-style Unix man page.

Re: Things I Wish I'd Known About Bash

#146
post #30

I wrote a book on Bash too. The most important thing for anyone to know about Bash is that it's intended as a command language, not a general purpose scripting language. If it's longer than 10 lines, or if it uses two or more variables, you should probably have written it in something other than Bash.

Would you consider non-trivial install scripts as an exception to this general rule? I mean, you wouldn't write some install script in ruby or python, right?

Isn't that what chef and Capistrano are at some level?

Re: Things I Wish I'd Known About Bash

#147
post #132
post #30

I wrote a book on Bash too. The most important thing for anyone to know about Bash is that it's intended as a command language, not a general purpose scripting language. If it's longer than 10 lines, or if it uses two or more variables, you should probably have written it in something other than Bash.

I think the 10 line limit seems a little harsh. Bash is great to prototype something, especially because of all the great commands at your disposal versus writing it yourself. e.g. grep, sed, cut are all commands I use frequently. Once you've got a working script and it proves useful or needs to scale - that's a good time to go the 'real language' route like Python.

> I think the 10 line limit seems a little harsh.

I think it's a fine guide. If I'm writing something that starts approaching a program rather than a few lines of utility-throw-away, it's time to at least immediately start co-developing in something more sane. My exception is for Makefiles, if one considers them "shell".

Re: Things I Wish I'd Known About Bash

#148

shellcheck ( https://www.shellcheck.net ) is an absolute godsend when writing Bash/POSIX sh scripts. It catches so many errors that I think it's a must have in every programmer's toolbox. It even catches bash-isms when you are targeting POSIX sh. It saved me many many hours of grief trying to debug shell scripts I wrote and changed the way I write them for the better.

shellcheck is amazing. I write enough shell scripts that I remember most of the syntax and tricks, but am far from an expert. shellcheck has taught me so many things and makes me feel more safe writing scripts in the event I forget one of the million gotchas.

Re: Things I Wish I'd Known About Bash

#149
post #62
post #30

I wrote a book on Bash too. The most important thing for anyone to know about Bash is that it's intended as a command language, not a general purpose scripting language. If it's longer than 10 lines, or if it uses two or more variables, you should probably have written it in something other than Bash.

I disagree. Here's how I decide: Do I need to manipulate rich data structures like hash-maps or nested lists? That sort of thing tends to stretch the capabilities of Bash to its limits and I tend to set the bar fairly low here. Is the program oriented around commands? If I'm gluing executable scripts and binaries, using bash is often superior to a scripting language. Argument passing is more natural and convenient an…

Great arguments. Add one: bash is a more lightweight dependency, frequently available even on windows, weird *nix versions and minimalistic environments (e.g busybox linux, fresh arch install, ...).

Re: Things I Wish I'd Known About Bash

#150
post #127
post #2

My take on the same topic: - use the unofficial strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/ - use parameter substitutions like ${foo#prefix}, ${foo%suffix} instead of invoking sed/awk - process substitution instead of named pipes: () - know the difference between an inline group {} and a subshell () - use printf "%q" when passing variables to another shell (e.g. assembling a command locall…

Parameter substitution is far from intuitive. Every time I have to open one of my older shell scripts (>3 months ago), I'm thankful I wrote comments. Otherwise I'd have to man/google things again. I really wish they'd use function names or something, instead (sub, etc.).

My "mnemonic" is that # means prefix, because every shell script starts with a shebang too. From this I can deduce that ## means longest prefix, therefore % and %% means suffix.
Post reply on HN