JMM’s

Bash notes

Because I forget how to use GNU Bash all the time.

Arrays

Here’s an example of reading in an array using null characters as delimiters. (It’s used in my FFmpeg notes.)

readarray -td '' argarray < <(printf -- '-i\0%s\0' *.mp3)
ffmpeg "${argarray[@]}" -filter_complex "concat=n=$(( ${#argarray[@]} / 2)):v=0:a=1" -map_metadata -1 -bitexact -y output.opus

Quoting

I never remember how to properly quote things. This Stack Overflow question has pretty good guidance, as does the Bash reference manual section on quoting. Seems like the easiest way is to use single quotes, for example:

echo 'What'\''s that?'

If you assign a string to a variable myvar, then doing

${myvar@Q}
will output a quoted version of it (see Shell Parameter Expansion (Bash Reference Manual)).

Parameter expansion

Here’s how to replace filename extensions (adapted from BashGuide/Parameters). Also see Shell Parameter Expansion (Bash Reference Manual) and possibly POSIX parameter expansions.

$ file="something.tar.gz"
$ echo $file
something.tar.gz
$ echo "${file%.*}.jpg"
something.tar.jpg
$ echo "${file%%.*}.jpg"
something.jpg

Here’s how to have a default string if the parameter is empty:

$ echo ${DISPLAY:-bar}
:0
$ echo ${foo:-bar}
bar

Keybindings

List keybindings

Use bind -p to list. See Bindable Readline Commands (Bash Reference Manual).

$ bind -p
"\C-x\C-g": abort
"\e\C-g": abort
"\C-j": accept-line
"\C-m": accept-line
# alias-expand-line (not bound)
# arrow-key-prefix (not bound)
# backward-byte (not bound)
"\C-b": backward-char
"\eOD": backward-char
"\e[D": backward-char
"\C-h": backward-delete-char
…

Keybinding questions

Just some questions I have that I should try to figure out later.

  • Not sure what M-p actually does (which is normally how I get the previous input in Emacs comint mode). I should probably rebind this.
  • Not sure how “emacs” keymap differs from others like “emacs-meta”.

“POSIX”

I don’t really use, or particularly care about, POSIX compliance or avoiding “bashisms”. Bash is free software that you can install on basically any system. Instead of worrying about how to make your shell script POSIX compliant, worry about how to get a proper GNU Bash onto your system.

I wasn’t even sure where the POSIX standard even is until today (2023-11-09). It looks like it’s available from The Open Group at https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html

To make it clear that you’re using GNU Bash, though, you may want to give your scripts the “.bash” extension. In Emacs, this will also use the Bash variant of “sh-mode”.