¿Qué es POSIXLY_CORRECT y qué lo hace cambiar (Centos 8.4)?

¿Qué es POSIXLY_CORRECT y qué lo hace cambiar (Centos 8.4)?

Estoy probando usando el migrate2rocky.shscript de GitHub:

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

Probé esto ayer y funcionó bien. Hoy volví a una instantánea para hacerlo de nuevo. Esta vez el script falló en la primera comprobación:

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

Específicamente, falla en la  $POSIXLY_CORRECTprueba (ejecuté el fragmento de código de forma independiente para verificarlo). Revisé la versión de bash en ejecución:

[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 ~]$

Por lo que puedo decir, POSIX es un conjunto estándar para facilitar la portabilidad de aplicaciones entre sistemas operativos tipo UNIX.

No se realizaron cambios en nuestros servidores para explicar por qué el script ya no funciona. Probé el script en servidores en los que aún no lo he usado y ocurre el mismo problema.

Todos los servidores son CentOS 8.4.

No sé qué $POSIXLY_CORRECThace y por qué falla ahora cuando ayer estuvo bien.

Por favor, avíseme si tiene alguna consulta, estoy realmente perdido.


Salida del sudo bash -x migrate2rocky.shcomando:

[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 ~]$

Curiosamente, el comando funciona, como puede ver arriba (pasa la  POSIXLY_CORRECTprueba y continúa probando los valores de BASH_VERSIONy EUID), cuando se ejecuta mediante el bashcomando " " en lugar de " sh", como hice ayer.

Respuesta1

El mensaje de error indica que no lo ejecutó con una versión del bashshell posterior a la versión 4.0. Presumiblemente, el script se basa en características que bashimplementa el shell que son diferentes o amplían el conjunto de características que prescribe el estándar POSIX para el lenguaje shell de Unix.

El final de su pregunta confirma que lo ejecutó con sh, que en su sistema puede ser algún shell distinto a bash. Incluso si shestá bashdisfrazado, sería el shell ejecutándose en modo POSIX.

Considere ejecutar el script con basho, si el script tiene una #!línea en la parte superior, simplemente haga que el script sea ejecutable (con chmod +x scriptname) y luego ejecútelo como ./scriptname.

La POSIXLY_CORRECTvariable de entorno es una variable que ayuda a las empresas de servicios públicos a seleccionar el comportamiento cuando la herramienta implementa un comportamiento que difiere de lo que prescribe el estándar POSIX.

El bashshell actuará ligeramente diferente en el modo POSIX (es decir set -o posix, si está habilitado o si el shell se inicia comosh ). Las diferencias se describen en la sección titulada "Modo Bash POSIX" en el bashmanual.

Respuesta2

Complementando la respuesta de Kusalananda con algunos detalles contextuales.

Desde elURL de Github vinculada, puedes ver que la primera línea del script es #!/bin/bash. Esta línea indica el intérprete que se utilizará para el script, que en este caso es el bashshell. En otras palabras, este script está pensado para ejecutarse con el bashshell.

La razón de esto queda clara con los comentarios en las líneas 35 y 26:

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

Los 'bashismos' son características específicas del bashcaparazón. Las matrices son un buen ejemplo de esto. Para garantizar que bashse utilice el caparazón, se verifican dos condiciones.

La BASH_VERSIONvariable es una variable especial establecida por el bashshell. Otros shells no establecen esta variable, por lo que basta con comprobar que esté definida para continuar.

La POSIXLY_CORRECTvariable entra en juego porque bashpuede ejecutarse en un modo diferente llamado modo POSIX. Este modo existe para garantizar la compatibilidad con otros shells, incluso con shells más antiguos. Para obtener esa compatibilidad, bashdesactive varias de sus funciones más nuevas. Nuevamente, esto rompería el script, por lo que no se puede ejecutar desde una bashinstancia en modo POSIX. Es por eso que la verificación está invertida, es decir, POSIXLY_CORRECTno se debe configurar. Se establece cuando bashse ejecuta en modo POSIX.

Como ya ha señalado en la pregunta, ejecutar el script, /bin/bashsegún lo previsto, pasa limpiamente las comprobaciones: BASH_VERSIONestá definido y POSIXLY_CORRECTno lo está.

información relacionada