Estou testando usando o migrate2rocky.sh
script do GitHub:
https://github.com/rocky-linux/rocky-tools/blob/main/migrate2rocky/migrate2rocky.sh
Testei isso ontem e funcionou bem. Hoje voltei a um instantâneo para fazer novamente. Desta vez, o script falhou na primeira verificação:
if [ -n "$POSIXLY_CORRECT" ] || [ -z "$BASH_VERSION" ]; then
printf '%s\n' "bash >= 4.0 is required for this script." >&2
exit 1
fi
Especificamente, ele falha no $POSIXLY_CORRECT
teste (executei o trecho de código de forma independente para verificar). Eu verifiquei a versão do bash em execução:
[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 ~]$
Pelo que sei, o POSIX é um conjunto padrão para facilitar a portabilidade de aplicativos entre sistemas operacionais do tipo UNIX.
Nenhuma alteração foi feita em nossos servidores para explicar por que o script não funciona mais. Testei o script em servidores nos quais ainda não usei e o mesmo problema ocorre.
Os servidores são todos CentOS 8.4.
Não sei o que $POSIXLY_CORRECT
faz e por que está dando erro agora, quando estava tudo bem ontem.
Por favor, deixe-me saber se você tiver alguma dúvida, estou realmente perdido.
Saída do sudo bash -x migrate2rocky.sh
comando:
[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 o comando funciona, como você pode ver acima (ele passa no POSIXLY_CORRECT
teste e passa a testar os valores de BASH_VERSION
and EUID
), ao rodar via bash
comando " " ao invés de " sh
", como fiz ontem.
Responder1
A mensagem de erro indica que você não o executou com uma versão do bash
shell mais recente que a versão 4.0. Presumivelmente, o script depende de recursos bash
implementados pelo shell que são diferentes ou estendem o conjunto de recursos prescritos pelo padrão POSIX para a linguagem shell Unix.
O final da sua pergunta confirma que você a executou sh
, que no seu sistema pode ser algum shell diferente de bash
. Mesmo que você sh
esteja bash
disfarçado, seria o shell rodando no modo POSIX.
Considere executar o script com bash
, ou, se o script tiver uma #!
linha - no topo, apenas torne o script executável (com chmod +x scriptname
) e execute-o como ./scriptname
.
A POSIXLY_CORRECT
variável de ambiente é uma variável que ajuda os utilitários a selecionar o comportamento quando a ferramenta implementa um comportamento diferente do prescrito pelo padrão POSIX.
O bash
shell agirá de maneira um pouco diferente no modo POSIX (ou seja, se set -o posix
estiver ativado ou se o shell for iniciado como sh
). As diferenças estão descritas na seção intitulada "Modo Bash POSIX" no bash
manual.
Responder2
Complementando a resposta de Kusalananda com alguns detalhes contextuais.
DeURL vinculado do Github, você pode ver que a primeira linha do script é #!/bin/bash
. Esta linha indica o intérprete a ser utilizado para o script, que neste caso é o bash
shell. Em outras palavras, este script deve ser executado com o bash
shell.
A razão para isso fica clara nos comentários nas linhas 35 e 26:
# These checks need to be right at the top because we start with bash-isms right # away in this script.
'Bash-ismos' são recursos específicos do bash
shell. Matrizes são um bom exemplo disso. Para garantir que o bash
shell seja usado, duas condições são verificadas.
A BASH_VERSION
variável é uma variável especial definida pelo bash
shell. Outros shells não definem esta variável, portanto, basta verificar se ela está definida para prosseguir.
A POSIXLY_CORRECT
variável entra em ação porque bash
pode ser executada em um modo diferente chamado modo POSIX. Este modo existe para garantir compatibilidade com outros shells, até mesmo shells mais antigos. Para obter essa compatibilidade, bash
desative vários de seus recursos mais recentes. Novamente, isso quebraria o script, portanto o script não pode ser executado a partir de uma bash
instância no modo POSIX. É por isso que a verificação está invertida, ou seja, POSIXLY_CORRECT
não deve ser definida. É definido quando bash
executado no modo POSIX.
Como você já observou na pergunta, a execução do script com /bin/bash
- conforme pretendido - passa de forma limpa nas verificações: BASH_VERSION
está definido e POSIXLY_CORRECT
não está.