Earlier quoted context omitted.
Those operators are in "2.6.4 Arithmetic Expansion" in your linked doc. See the link to "Arithmetic Precision and Operations"[1]. [1]: https://web.archive.org/web/20201219013931/https://pubs.open...
Thank you. This helps. But does that mean a POSIX shell, or any other UNIX utility, must implement these operators. Using them in shell scripts makes the scripts non-portable, e.g., Almquist sh, NetBSD Almquist sh or Debian Almquist sh do not support them. Maybe the author of the "Pure POSIX Sh Bible" always runs Bash in --posix mode. Hence "Pure POSIX sh".
Pure Sh Bible
121–130 of 138 posts
Re: Pure Sh Bible
#122Earlier quoted context omitted.
It's well worth learning to use printf instead of echo to avoid all the various ways that echo can break or is not well defined. https://mywiki.wooledge.org/BashPitfalls#echo_.24foo
The %q format alone justifies learning about printf. Vanilla echo is for chumps.
Re: Pure Sh Bible
#123Earlier quoted context omitted.
Those operators are in "2.6.4 Arithmetic Expansion" in your linked doc. See the link to "Arithmetic Precision and Operations"[1]. [1]: https://web.archive.org/web/20201219013931/https://pubs.open...
Thank you. This helps. But does that mean a POSIX shell, or any other UNIX utility, must implement these operators. Using them in shell scripts makes the scripts non-portable, e.g., Almquist sh, NetBSD Almquist sh or Debian Almquist sh do not support them. Maybe the author of the "Pure POSIX Sh Bible" always runs Bash in --posix mode. Hence "Pure POSIX sh".
This just means that you're going to have to find a better way to describe the level of backwards compatibility you're going for other than "POSIX compliance", because these do seem to be required in the standards.
Re: Pure Sh Bible
#124I have to take exception to some of this; it's "technically correct" but like much of shell, likely full of terrifying edge cases that are best avoided. For instance, using eval to have variables with variable names is madness. $ var="world" $ eval "hello_$var=value" $ eval printf '%s\n' "\$hello_$var" I suppose the fancy business with printf is flexing, but I suspect the majority of people scanning documents like th…
I'm scratching my head at most of it and there's large portions that are incomplete or trivial. bash is ubiquitous. If you're trying to develop an entire web framework to run on a Bourne shell from busybox, dash, or FreeBSD 4, there's probably a better way to do it. Use the tool you have, not a hypothetical one compatible with 1983. YAGNI. Here's a common pattern for appending to PATH system-wide once: # /etc/profile…
I'd personally try to minimise the use of eval, e.g.
prepend() {
local val
eval "val=\$$1"
export "$1=$2${val:+${3-:}$val}"
}
append() {
local val
eval "val=\$$1"
export "$1=${val:+$val${3-:}}$2"
}Re: Pure Sh Bible
#125I have to take exception to some of this; it's "technically correct" but like much of shell, likely full of terrifying edge cases that are best avoided. For instance, using eval to have variables with variable names is madness. $ var="world" $ eval "hello_$var=value" $ eval printf '%s\n' "\$hello_$var" I suppose the fancy business with printf is flexing, but I suspect the majority of people scanning documents like th…
It's well worth learning to use printf instead of echo to avoid all the various ways that echo can break or is not well defined. https://mywiki.wooledge.org/BashPitfalls#echo_.24foo
Re: Pure Sh Bible
#126Earlier quoted context omitted.
> where things get easier if you just switch to a language with less caveats (like Python). For general, non-domain specific things, it gets IMO easier by two main reasons 1) obviously when using tools where one has more experience with, but 2) also when the tool is more widely available, and POSIX shell is probably one of the most (by default) available interpreters with a somewhat human-friendly input mode there is…
> They use the printf "%f" float format conversion so `printf "%f" 2e3` will work just fine, whereas using something that definitively is not a float makes printf exit with an error code as it fails to format the value as float, failing this check. You are of course correct (sorry to sound like a language model), I missed the printf.
Re: Pure Sh Bible
#127Regarding conditional expressions: I found something neat recently. The coreutils version of `test` doesn't have this, and when you use `test`, typically what you're using is the coreutils one. But if you use `builtin test` to force the bash builtin variant of `test`, this has a nice `-v` switch, which allows you to check if a variable is set. I found out about this recently when I had to use it in my bash argument p…
The usual way to check if $2 is present is to use `[ $# -ge 2 ]`. For named variables, I like to use `[ "${myvar+set}" != "set" ]` (the parameter expansion `${myvar+word}` expands to "word" if myvar is set or "" if it is unset, see https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...).
(Often people want to treat an empty value as unset, so they just use `[ -n "$myvar" ]` to check that the value is non-empty. If you enable `set -u` to treat references to unset variables as errors, this should instead be `[ -n "${myvar-}" ]`.)
Some comments on the script you linked:
I highly recommend ShellCheck (https://www.shellcheck.net/), it picks up a legitimate issue in your script: `tr -s [:alpha:] Y` should be `tr -s "[:alpha:]" Y` (otherwise it fails if the current directory contains a single-letter filename).
Also, you should use `printf "%s\n" "$var"` instead of `echo "$var"` in case $var is "-n" for example.
Re: Pure Sh Bible
#128Regarding conditional expressions: I found something neat recently. The coreutils version of `test` doesn't have this, and when you use `test`, typically what you're using is the coreutils one. But if you use `builtin test` to force the bash builtin variant of `test`, this has a nice `-v` switch, which allows you to check if a variable is set. I found out about this recently when I had to use it in my bash argument p…
If you already assume bash, then you don’t need the “-v” option to the “test” builtin; just do if [ "${foo+some_string}" = "" ]; then echo "foo is unset" fi or, in your case: if test "${2+x}" = "" # i.e. if $2 is not set
Re: Pure Sh Bible
#129i dont know about anyone else. but since ChatGPT, my shell game is probably the one that is most levelled up. A lot of things i would either do manually because i had forgotten shell programming, or i would have done in a seperate pyenv with 2-3 packages i can get done in about 4 minutes.
Re: Pure Sh Bible
#130Earlier quoted context omitted.
I'm scratching my head at most of it and there's large portions that are incomplete or trivial. bash is ubiquitous. If you're trying to develop an entire web framework to run on a Bourne shell from busybox, dash, or FreeBSD 4, there's probably a better way to do it. Use the tool you have, not a hypothetical one compatible with 1983. YAGNI. Here's a common pattern for appending to PATH system-wide once: # /etc/profile…
Your "zsh/bash" code doesn't actually use any zsh/bash-only features, so it is compatible with POSIX sh. But you have a quoting bug: you should escape the `$` in `$2` and `${3...}` to protect from double-eval. I'd personally try to minimise the use of eval, e.g. prepend() { local val eval "val=\$$1" export "$1=$2${val:+${3-:}$val}" } append() { local val eval "val=\$$1" export "$1=${val:+$val${3-:}}$2" }