
More Things I Wish I’d Known About Bash - jesperht
https://zwischenzugs.com/ten-more-things-i-wish-id-known-about-bash/
======
ckuehl
This is a somewhat dangerous pattern for picking temporary files (from #8):

    
    
        $ NEWFILE=/tmp/newfile_${RANDOM}
        $ touch $NEWFILE
    
    

The problem is that any user on the box can create files under /tmp. An
attacker can set up a bunch of symlinks like /tmp/newfile_1, ...,
/tmp/newfile_99999 pointing to a file owned by your user. When your script
then writes into this temporary file, you'll write through the symlink and
clobber one of your own files. Especially dangerous if root :)

This has been a historic source of software vulnerabilities (often with the
PID used instead as the guessable component instead of random, though). One
recommended alternative is to use the `mktemp` command instead.

~~~
jwilk
Nitpick: $RANDOM gives you an integer between 0 and 32767 (inclusive).

------
guhcampos
Portuguese speakers have counted for a long time with this gem, simply the
best Bash doc/cheat sheet I've ever seen on the web. This is probably my
oldest bookmark still relevant after 15 years.

It's in portuguese and I'm not sure if there's an official translation, yet
it's easy enough to decipher if you know bash, and Google Translate will do a
pretty decent job.

I gift you "Aurelio's Swiss Army Knife of the Bash Shell" \-
[http://aurelio.net/shell/canivete/](http://aurelio.net/shell/canivete/)

~~~
gerdesj
Thanks for the heads up - it does work via translate.

I'll drop this: [http://tldp.org/LDP/abs/html/](http://tldp.org/LDP/abs/html/)
If anyone, who has to do anything BASH related, has not seen it then they
should!

~~~
gdavisson
I'd recommend _against_ the Advanced Bash-Scripting Guide -- it uses a lot of
bad practices (like unquoted variable references!) that you're better off not
learning. Instead, check out
[http://mywiki.wooledge.org/BashGuide](http://mywiki.wooledge.org/BashGuide)
and [http://mywiki.wooledge.org/BashFAQ](http://mywiki.wooledge.org/BashFAQ).
Also, [http://www.shellcheck.net](http://www.shellcheck.net) is a good
automated tool for sanity-checking syntax errors and common mistakes.

------
_kst_
As I mentioned in my comment on the article, setting $TMOUT if you want a
timeout on a 'read' command is unnecessary and unclear. Just use "read -t":

    
    
        read -t 5 foo || foo='No reply'
    

Setting $TMOUT affects all following 'read' commands. Also, setting $TMOUT in
an interactive shell sets a timeout for a response to the primary prompt,
terminating the shell if the user doesn't respond in time.

------
gvalkov
Fiy, heredocs also have a variant that strips all leading tab characters.
Quoting from `man 1 bash`:

    
    
      If the redirection operator is <<-, then all leading   
      tab characters are stripped  from  input  lines  and  
      the line containing delimiter.  This allows here-
      documents within shell scripts to be indented in a  
      natural fashion.

~~~
Xophmeister
There’s also a variant, where you single quote the marker, that won’t expand
variables:

    
    
        cat <<‘EOF’
        This will not be ${expanded}
        EOF

------
hyperpape
I imagine most uses of random in Bash don't need to be that robust, but it
might be worth mentioning that ${RANDOM}${RANDOM} has a lot of bias as a
random number generator.

~~~
zwischenzug
Fair point - have updated accordingly.

~~~
_kst_
If you want 30 rather than 15 bits of randomness:

    
    
        echo $(((RANDOM << 15) + RANDOM))

------
antoineMoPa
"Sigh. Hit ‘up’, ‘left’ until at the ‘p’ and type ‘e’ and return.". My
solution for this one would be :

UP CTRL-A RIGHT RIGHT e

Which needs less thinking and 6 keystrokes instead of 8.

~~~
hiq
I don't like to use arrow keys, and on my system the following works: CTRL-P
CTRL-A CTRL-F CTRL-F e I also prefer this to the solution in the article.

~~~
chrissoundz
Potentially of interest:
[https://github.com/Fakerr/goto](https://github.com/Fakerr/goto) sort of like
the easymotion vim plugin.

------
SteveNuts
I'm so happy that Bash is getting the love it deserves.

~~~
zwischenzug
Me too!

------
nerdponx
Just another plug for Zsh: it has all of these features and then some.

\- Safe-by-default parameter expansion: no word splitting unless you ask for
it, even if you don't quote the expansion.

\- Ability to use histoy expansions (like !!:gs/foo/bar) on parameter
expansions, meaning "${foo:A:h}" is equivalent to "$(dirname $(realpath
$foo))"

\- Much better array support, including both integer-indexed and associative
arrays

\- A built-in CLI option parser that's pretty robust ("zparseopts")

\- Lazy-loaded functions

\- Floating-point arithmetic

~~~
barrkel
Production servers don't generally have zsh available, while most have bash.
That means that ssh sessions will use a different shell, and scripts I write
will use a different shell. And so, the upside for using some funky shell
locally is greatly reduced.

Whereas if I stick with bash, I can run my scripts almost everywhere and
almost every server I ssh into has a familiar environment. Thus my knowledge
of edge cases and scripting idioms from bash pay dividends.

For situations where I need better arrays, associative arrays, floating point
arithmetic, I'm probably better off writing it in an actual scripting
language.

~~~
nerdponx
Fair enough! One tends to get spoiled with Zsh, trying to go back to Bash.

In the past I've actually downloaded Zsh, compiled it from source, and ran it
out of ~/.local/bin with absolutely no issues. But that's not something I'd
advise.

------
awll
_Sigh. Hit ‘up’, ‘left’ until at the ‘p’ and type ‘e’ and return._

One could also use <c-p>,<c-a> and <c-f> to achieve the same result much
quicker.

~~~
binaryphile
Yup. The moment you need editing capabilities more sophisticated than those
three keys, though, I recommend switching to vi input mode (set -o vi) if you
are familiar with vim keybindings. Although tapping Esc is not as quick as
Ctrl (or, my chosen alternative, Ctrl-[), you have an entire library of
editing commands already at your beck and call. I find that using 'f' or 'F'
and '.' more quickly triangulates the problem area of the text in most cases.

Of course, if you are an emacs user, more power to you with the emacs
bindings.

~~~
DrRobinson
IMO you might as well run "fc" (if you have vim set as your editor) in that
case, rather than changing mode.

~~~
jwilk
Or, if you already started editing a line, and decided that you'd rather
finish it in a proper editor, you can press Ctrl+X Ctrl+E.

~~~
TheGrassyKnoll
Didn't know that one, thanks.

------
dorfsmay
Interesting, most of these are from korn shell and well documented in "The
korn shell command and programming language" by Bolsky and Korn.

------
iamdave
Well that first example with the mistyped grep command just blew my mind.

------
partycoder
I agree with most of it except for:

    
    
        ${RANDOM}${RANDOM}
    

A preferred way would be

    
    
        od -vAn -N4 -tu4 < /dev/urandom
    

/dev/urandom gives you random bytes, od dumps them in different formats (e.g:
hex, octal, decimal and such).

This takes 4 random bytes and outputs them as a 4 byte unsigned int.

~~~
jwilk
Explanation of options:

-v: Don't suppress duplicate lines. (It doesn't make a difference here, because there's always only one line.)

-An: Don't write input offsets.

-N4: Read at most 4 bytes.

-tu4: Print 4-byte unsigned integers.

~~~
alinspired
[https://explainshell.com/explain?cmd=od+-vAn+-N4+-tu4](https://explainshell.com/explain?cmd=od+-vAn+-N4+-tu4)

------
coroxout
I use pushd and popd every day. If you forget what's in the stack you can see
what's in it by using the "dirs" command.

You can also use pushd -n (where n is a number, although I usually end up
needing trial and error to get the right one) to rotate the list of dirs
without removing any from the stack - useful if the list has more than 2
directories, or 2+ directories you need to switch between repeatedly.

pushd and popd also work out of the box in Windows command prompt, although
you don't get "dirs" or any fancier options like in bash, just push and pop on
a plain old stack.

------
zwischenzug
Previous post discussion:
[https://news.ycombinator.com/item?id=16084763](https://news.ycombinator.com/item?id=16084763)

------
sli

        ^x^y^
    

Is that third caret necessary? I've never had to include it. Although that may
be zsh taking a shortcut on bash syntax.

~~~
bewuethr
It's optional, also in Bash, even though I can't find it explicitly mentioned
in the manual.

------
7kmph
Things I Wish I’d Known About Bash: don't use it for script

------
cryptonector
But you really should know that set -e is broken.

~~~
cryptonector
So... why the downvotes? Is it not the case that set -e is broken? Or is it
that I provided too little detail? Or is it that it's broken in the same way
in all shells?

FWIW, the bug (yes, it's a bug that the Open Group has decided is not a bug,
but it really cannot be anything other than a bug!) is this: non-zero exits by
commands/functions are ignored when invoked by functions invoked in a
conditional expression context.

