1

I am testing using the migrate2rocky.sh script from GitHub:

https://github.com/rocky-linux/rocky-tools/blob/main/migrate2rocky/migrate2rocky.sh

I tested this yesterday and it worked fine. Today I reverted to a snapshot to do it again. This time the script failed on the first check:

if [ -n "$POSIXLY_CORRECT" ] || [ -z "$BASH_VERSION" ]; then
    printf '%s\n' "bash >= 4.0 is required for this script." >&2
    exit 1
fi

Specifically, it fails on the $POSIXLY_CORRECT test (I ran the code snippet independently to verify).  I checked the running bash version:

[user@server ~]$ rpm -qa | grep bash
bash-completion-2.7-5.el8.noarch
bash-4.4.20-1.el8_4.x86_64
[user@server ~]$ echo $BASH_VERSION
4.4.20(1)-release
[user@server ~]$ echo $POSIXLY_CORRECT

[user@server ~]$

From what I can tell POSIX is a standard set to ease application portability between UNIX-like OSs.

No changes were made on our servers to explain why the script no longer works. I tested the script on servers I haven't used the script on yet and the same issue occurs.

The servers are all CentOS 8.4.

I don't know what the $POSIXLY_CORRECT does and why it's erroring now when it was fine yesterday.

Please let me know if you have any queries, I'm really lost.


Output of sudo bash -x migrate2rocky.sh command:

[user@server ~]$ sudo bash -x migrate2rocky.sh
+ '[' -n '' ']'
+ '[' -z '4.4.20(1)-release' ']'
+ ((  BASH_VERSINFO < 4  ))
+ ((  EUID != 0  ))
+ logfile=/var/log/migrate2rocky.log
+ truncate -s0 /var/log/migrate2rocky.log
+ exec
++ tee -a /var/log/migrate2rocky.log
++ tee -a /var/log/migrate2rocky.log
+ errcolor=
+ blue=
+ nocolor=
+ export LANG=en_US.UTF-8
+ LANG=en_US.UTF-8
+ shopt -s nullglob
+ SUPPORTED_MAJOR=8
+ SUPPORTED_PLATFORM=platform:el8
++ arch
+ ARCH=x86_64
+ gpg_key_url=https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-rockyofficial
+ gpg_key_sha512=88fe66cf0a68648c2371120d56eb509835266d9efdf7c8b9ac8fc101bdf1f0e0197030d3ea65f4b5be89dc9d1ef08581adb068815c88d7b1dc40aa1c32990f6a
+ declare -A repo_urls
+ repo_urls=([rockybaseos]="https://dl.rockylinux.org/pub/rocky/${SUPPORTED_MAJOR}/BaseOS/$ARCH/os/" [rockyappstream]="https://dl.rockylinux.org/pub/rocky/${SUPPORTED_MAJOR}/AppStream/$ARCH/os/")
+ unset CDPATH
+ convert_info_dir=/root/convert
+ unset convert_to_rocky reinstall_all_rpms verify_all_rpms update_efi
+ noopts=0
+ getopts hrVR option
+ ((  ! noopts  ))
+ usage
+ printf '%s\n' 'Usage: migrate2rocky.sh [OPTIONS]' '' Options: '-h Display this help' '-r Convert to rocky' '-V Verify switch' '   !! USE WITH CAUTION !!'
Usage: migrate2rocky.sh [OPTIONS]

Options:
-h Display this help
-r Convert to rocky
-V Verify switch
   !! USE WITH CAUTION !!
+ exit 1
[user@server ~]$

Curiously the command works, as you can see above (it gets past the POSIXLY_CORRECT test and goes on to test the values of BASH_VERSION and EUID), when running via "bash" command rather than "sh", as I did yesterday.

2
  • That condition evaluates as - POSIXLY_CORRECT is defined or BASH_VERSION is undefined. It shouldn't be true with the conditions you have described. Can you add a '-x' parameter and rerun the script? You would either add it to the shebang line as /bin/bash -x, or you can run the script as bash -x migrate2rocky.sh.
    – Haxiel
    Commented Jun 15, 2021 at 13:30
  • Edited post with command output as requested. Curiously the script passes the check when using the "bash" command instead of "sh". Commented Jun 15, 2021 at 14:06

2 Answers 2

4

The error message indicates that you did not run it with a release of the bash shell newer than release 4.0. Presumably the script relies on features that the bash shell implements that are different from or extends the set of features that the POSIX standard for the Unix shell language prescribes.

The end of your question confirms that you ran it with sh, which on your system may be some shell other than bash. Even if your sh is bash in disguise, it would be the shell running in POSIX mode.

Consider running the script with bash, or, if the script has a #!-line at the very top, just make the script executable (with chmod +x scriptname) and then run it like ./scriptname.

The POSIXLY_CORRECT environment variable is a variable that helps utilities select behavior when the tool implements a behavior that differs from what the POSIX standard prescribes.

The bash shell will act slightly differently in POSIX mode (i.e. if set -o posix is enabled, or the shell is started as sh). The differences are described in th section entitled "Bash POSIX Mode" in the bash manual.

1
  • Thanks for the info. It appears I need to do research into the different kind of shells and their differences. As you explained, running with "bash" works as does making it executable and running with ./script. I will endeavour to understand this myself as it's clear I don't currently. I appreciate your time. Commented Jun 15, 2021 at 15:28
0

Complementing Kusalananda's answer with some contextual details.

From the linked Github URL, you can see that the first line of the script is #!/bin/bash. This line indicates the interpreter to be used for the script, which in this case is the bash shell. In other words, this script is intended to be executed with the bash shell.

The reason for this is made clear with the comments on line 35 & 26:

# These checks need to be right at the top because we start with bash-isms right
# away in this script.

'Bash-isms' are features specific to the bash shell. Arrays are a good example of this. To ensure that the bash shell is used, two conditions are checked.

The BASH_VERSION variable is a special variable set by the bash shell. Other shells don't set this variable, so simply checking that it is defined is sufficient to proceed.

The POSIXLY_CORRECT variable comes into play because bash can run in a different mode called POSIX mode. This mode exists to ensure compatibility with other shells, even older shells. To get that compatibility, bash turns off a number of its newer features. Again, this would break the script, so the script cannot be executed from a bash instance in POSIX mode. This is why the check is inverted, that is POSIXLY_CORRECT should not be set. It is set when bash runs in POSIX mode.

As you have already noted in the question, running the script with /bin/bash - as intended - cleanly passes the checks : BASH_VERSION is defined, and POSIXLY_CORRECT is not.

1
  • 1
    Bash in POSIX mode still comes with a non-POSIX echo and thus is not POSIX compliant. To set bash into POSX mode, you need to call: set -o posix and shopt -s xpg_echo.
    – schily
    Commented Jun 24, 2021 at 12:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .