0

Is it possible to know from which specific version of bash a particular built-in is made available from the command-line? Is it only possible by browsing through release notes for each of the versions or a simpler way exists?

  • The release notes and changelogs are notoriously unreliable. The best is to take a bigger hammer at it -- bisect and build the same way as you do with a bug. Check git-bisect(1), though you may use a collection of already built binaries instead. – mosvy Jun 18 at 9:16
1

I don't think there's a way to ask Bash for which version a feature was added. The closest way of testing it that I can think of, using BASH_COMPAT or the compatXY options, don't include builtin availability (even though some affect builtin behaviour):

compat31

If set, Bash changes its behavior to that of version 3.1 with respect to quoted arguments to the conditional command's =~ operator and with respect to locale-specific string comparison when using the [[ conditional command's < and > operators. Bash versions prior to bash-4.1 use ASCII collation and strcmp(3); bash-4.1 and later use the current locale's collation sequence and strcoll(3).

compat32

If set, Bash changes its behavior to that of version 3.2 with respect to locale-specific string comparison when using the [[ conditional command's < and > operators (see previous item) and the effect of interrupting a command list. Bash versions 3.2 and earlier continue with the next command in the list after one terminates due to an interrupt.

compat40

If set, Bash changes its behavior to that of version 4.0 with respect to locale-specific string comparison when using the [[ conditional command's < and > operators (see description of compat31) and the effect of interrupting a command list. Bash versions 4.0 and later interrupt the list as if the shell received the interrupt; previous versions continue with the next command in the list.

compat41

If set, Bash, when in POSIX mode, treats a single quote in a double-quoted parameter expansion as a special character. The single quotes must match (an even number) and the characters between the single quotes are considered quoted. This is the behavior of POSIX mode through version 4.1. The default Bash behavior remains as in previous versions.

compat42

If set, Bash does not process the replacement string in the pattern substitution word expansion using quote removal.

compat43

If set, Bash does not print a warning message if an attempt is made to use a quoted compound array assignment as an argument to declare, makes word expansion errors non-fatal errors that cause the current command to fail (the default behavior is to make them fatal errors that cause the shell to exit), and does not reset the loop state when a shell function is executed (this allows break or continue in a shell function to affect loops in the caller's context).

compat44

If set, Bash saves the positional parameters to BASH_ARGV and BASH_ARGC before they are used, regardless of whether or not extended debugging mode is enabled.

There really isn't much of a use-case for this. The usual advice for situations that checks version information for feature availability is to check for the feature's (in this case, builtin's) availability directly instead - after all, even a version which has this feature might have it disabled at compile-time.

For example:

$ for s in bash /bin/bash; do
 for b in compopt help; do
  "$s" -c 'echo "$1" is $([[ $(type "$1" 2>/dev/null) =~ "shell builtin" ]] || echo not) a builtin in "$BASH_VERSION"' _ $b;
 done;
done
compopt is a builtin in 5.0.7(1)-release
help is a builtin in 5.0.7(1)-release
compopt is not a builtin in 3.2.57(1)-release
help is a builtin in 3.2.57(1)-release
  • Thanks! It is a neat little trick, but I would really like to know the origin version of builtin. I know its close to impossible, but would a keep an eye for more answers – Inian Jun 18 at 6:26
  • @Inian the NEWS and CHANGES files should part of the installation (they combine release notes for all previous versions as well). So you could try grepping or parsing those: awk -v newb="new `.*' builtin" '/---+/ || !version {version=$12} $0 ~ newb {print version, $0}' NEWS paste.ubuntu.com/p/sJVNcNM2ms – muru Jun 18 at 6:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.