1

From https://unix.stackexchange.com/a/458074/674

arithmetic expansions are also subject to split+glob so should also be quoted (shift "$((OPTIND - 1))") (here not a problem though as you're using bash which doesn't inherit $IFS from the environment and you're not modifying IFS earlier in the script, but still good practice).

Is arithmetic expansion related to IFS in some way?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Tim
  • 98,580
  • 191
  • 570
  • 977

1 Answers1

3

The result of an unquoted arithmetic expansion undergoes file name globbing (wildcard expansion) and word (field) splitting, like any other unquoted expansion. It's pretty useless and a few shells don't do it but it's what historical shells did (because it was easier to implement) and so it's what POSIX standardized.

The result of an arithmetic expansion is just a string of - and digits, so it can never contain a wildcard. (A few shells have floating point and can also include ., + and letters.) Since it can't contain whitespace, it is normally not subject to field splitting either. However field splitting is configurable through IFS: the field separators are the characters of IFS. Including digits in IFS is extremely rare and is a pretty silly things to do, but if you want to write fully robust code, you need to protect against this. This matters more if the result may be negative, because including a dash in IFS is not as silly.

POSIX states that the shell must set IFS to its default value when it starts, so that scripts aren't affected by a value of IFS that might be in the environment. (It's uncommon to export IFS, but someone could do it.) However, some widespread shells (dash, Busybox sh) keep whatever value of IFS is in the environment, so a robust shell script should set explicitly IFS to its default value (or unset it, which has the same effect) if it contains any unquoted expansion.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • 1
    Note that pdksh and zsh (even in sh emulation) and IIRC earlier versions of `yash` don't do word splitting upon arithmetic expansions. – Stéphane Chazelas Jul 25 '18 at 06:26
  • Also note that some shells like `dash` still import `$IFS` from the environment. – Stéphane Chazelas Jul 25 '18 at 06:27
  • In `zsh`, `#` can also occur in an arithmetic expansion and is an extended glob operator, but `zsh` doesn't do globbing upon arithmetic expansion. In ksh93, yash and zsh, it's not only digits and `-` as they support floating points. There can also be `e`, `+`, `nan`, `inf` (with variation of case). – Stéphane Chazelas Jul 25 '18 at 06:36
  • (and `.` (or `,` in `ksh93` or `yash` depending on the locale) obviously) – Stéphane Chazelas Jul 25 '18 at 07:35