首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是POSIXLY_CORRECT,是什么使它改变(CentOS8.4)?

什么是POSIXLY_CORRECT,是什么使它改变(CentOS8.4)?
EN

Unix & Linux用户
提问于 2021-06-15 12:27:10
回答 2查看 2.3K关注 0票数 1

我正在使用来自migrate2rocky.sh的GitHub脚本进行测试:

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

我昨天测试了这个,效果很好。今天,我又回到了一张快照中,再做一次。这一次,脚本在第一次检查时失败:

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

具体来说,它在$POSIXLY_CORRECT测试中失败(我独立运行了代码片段以验证). I检查了运行的bash版本:

代码语言:javascript
复制
[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 ~]$

据我所知,POSIX是一个标准集,可以简化类似UNIX的OSs之间的应用程序可移植性。

在我们的服务器上没有进行任何更改来解释为什么脚本不再工作。我在尚未使用脚本的服务器上测试了脚本,并出现了同样的问题。

服务器都是CentOS 8.4。

我不知道$POSIXLY_CORRECT是做什么的,也不知道昨天天气好的时候为什么会出错。

如果你有任何疑问,请告诉我,我真的迷路了。

sudo bash -x migrate2rocky.sh命令的输出:

代码语言:javascript
复制
[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 ~]$

奇怪的是,正如您在上面看到的那样,当通过“POSIXLY_CORRECT”命令而不是"sh“运行时,命令可以正常工作(它通过更高级的bash测试,然后继续测试BASH_VERSIONEUID的值),就像我昨天做的那样。

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2021-06-15 14:17:11

错误消息表明,您没有使用比版本4.0更新的bash外壳版本来运行它。据推测,该脚本依赖于bash shell实现的特性,这些特性不同于或扩展了用于Unix语言的POSIX标准所规定的特性集。

问题的结尾证实了您使用sh运行它,在您的系统中,这可能是一些bash以外的shell。即使您的sh是伪装的bash,它也是以POSIX模式运行的shell。

考虑使用bash运行脚本,或者,如果脚本顶部有一个#!-line,只需使脚本可执行(使用chmod +x scriptname),然后像./scriptname一样运行它。

POSIXLY_CORRECT环境变量是一个变量,当工具实现与POSIX标准所规定的行为不同的行为时,它帮助实用程序选择行为。

在POSIX模式下,bash外壳的工作方式略有不同(即,如果启用了set -o posix,或者以sh的形式启动了shell )。这些差异在bash手册中题为“D15”的部分中进行了描述。

票数 4
EN

Unix & Linux用户

发布于 2021-06-20 16:25:07

用一些上下文的细节来补充克莎拉南达的回答。

链接Github中,您可以看到脚本的第一行是#!/bin/bash。这一行指示要用于脚本的解释器,在本例中是bash shell。换句话说,这个脚本打算用bash外壳来执行。

第35和26行的评论说明了这一点的原因:

这些检查必须在最上面,因为我们从这个脚本中的bash-ism开始。

‘features’是bash shell特有的特性。数组就是一个很好的例子。为了确保使用bash外壳程序,将检查两个条件。

BASH_VERSION变量是由bash shell设置的一个特殊变量。其他shell不设置此变量,因此只需检查它是否已定义就足以继续操作。

POSIXLY_CORRECT变量起作用是因为bash可以在一种称为POSIX模式的不同模式下运行。此模式的存在是为了确保与其他shell,甚至更旧的shell的兼容性。为了获得这种兼容性,bash关闭了它的许多新特性。同样,这会破坏脚本,因此不能从POSIX模式下的bash实例执行脚本。这就是为什么检查是倒转的,即不应该设置POSIXLY_CORRECT。它是在POSIX模式下运行bash时设置的。

正如您在问题中已经指出的,使用/bin/bash运行脚本--正如预期的那样--可以通过检查:定义了BASH_VERSION,而没有定义POSIXLY_CORRECT

票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/654350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档