如何克服Linux上的ksh与AIX / Solaris / HPUX上安装的ksh之间的不兼容?

如何克服Linux上的ksh与AIX / Solaris / HPUX上安装的ksh之间的不兼容?

How to overcome an incompatibility between the ksh on Linux vs. that installed on AIX/Solaris/HPUX?

我参与了将包含数百个ksh脚本的系统从AIX,Solaris和HPUX移植到Linux的过程。我发现ksh在两个系统上的行为方式存在以下差异:

1
2
3
4
5
6
7
8
9
#!/bin/ksh
flag=false
echo"a
b" | while read x
do
    flag=true
done
echo"flag = ${flag}"
exit 0

在AIX,Solaris和HPUX上,输出为" flag = true";在Linux上,输出为" flag = false"。

我的问题是:

  • 是否可以设置环境变量以使Linux的ksh像
    其他Os的?失败:
  • Linux的ksh上是否有一种选项可以获取所需的行为?失败:
  • 是否有可用于Linux且具有所需行为的ksh实现?

其他说明:

  • 在AIX,Solaris和HPUX上,ksh是ksh88的变体。
  • 在Linux上,ksh是公共域ksh(pdksh)
  • 在AIX上,Solaris和HPUX dtksh和ksh93(在其中安装了它们)与ksh一致
  • 我可以访问的Windows NT系统:Cygwin和MKS NT与Linux一致。
  • 在AIX,Solaris和Linux上,bash一致,给出错误的结果(从我看来)" flag = false"。

下表总结了系统存在的问题:

1
2
3
4
5
6
7
8
9
10
11
uname -s       uname -r                   which ksh          ksh version                     flag =
========       ========                   =========          ===========                     ======
Linux          2.6.9-55.0.0.0.2.ELsmp     /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
AIX            3                          /bin/ksh           Version M-11/16/88f             true    // AIX 5.3
                                          /bin/ksh93         Version M-12/28/93e             true
SunOS          5.8, 5.9 and 5.10          /bin/ksh           Version M-11/16/88i             true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
HP-UX          B.11.11 and B.11.23        /bin/ksh           Version 11/16/88                true
                                          /usr/dt/bin/dtksh  Version M-12/28/93d             true
CYGWIN_NT-5.1  1.5.25(0.156/4/2)          /bin/ksh           PD KSH v5.2.14 99/07/13.2       false
Windows_NT     5                          .../mksnt/ksh.exe  Version 8.7.0 build 1859...     false    // MKS

更新资料

经过我公司人员的一些建议后,我们决定对代码进行以下修改。无论使用"真实的" ksh(ksh88,ksh93)还是任何ksh克隆(pdksh,MSK ksh),这都给我们相同的结果。这对于bash也可以正常使用。

1
2
3
4
5
6
7
8
9
10
#!/bin/ksh
echo"a
b"> junk
flag=false
while read x
do
    flag=true
done < junk
echo"flag = ${flag}"
exit 0

感谢jj33先前接受的答案。


不要在Linux上使用pdksh,而要使用kornshell.org中的" real" ksh。 pdksh是ksh的盲目重新实现。 kornshell.org是原始的korn外壳,可追溯到25年左右(David Korn编写的外壳)。 AIX和Solaris使用的是原始ksh的版本,因此kornshell.org版本通常是功能完善且错误完整的。在使用SunOS / Solaris之后,安装kornshell.org ksh通常是在新的Linux机器上要做的第一件事...


经过我公司人员的一些建议后,我们决定对代码进行以下修改。无论使用"真实的" ksh(ksh88,ksh93)还是任何ksh克隆(pdksh,MSK ksh),这都给我们相同的结果。这对于bash也可以正常使用。

1
2
3
4
5
6
7
8
9
10
#!/bin/ksh
echo"a
b"> junk
flag=false
while read x
do
    flag=true
done < junk
echo"flag = ${flag}"
exit 0

感谢jj33为先前接受的答案。


这是回显" n"问题的另一种解决方案

脚步:

  • 查找ksh软件包名称
  • $ rpm -qa --queryformat"%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})
    " | grep"ksh"
    ksh-20100621-19.el6_4.3(x86_64)

  • 卸载ksh
    $ sudo yum remove ksh-20100621-19.el6_4.3.x86_64

  • 下载pdksh-5.2.14-37.el5_8.1.x86_64.rpm(请检查32位或64位操作系统并选择正确的pkg)

  • 安装pdksh-5.2.14-37.el5_8.1.x86_64.rpm

  • $ sudo yum -y install /SCRIPT_PATH/pdksh-5.2.14-37.el5_8.1.x86_64.rpm

    安装PDKSH之前的输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $ ora_db_start_stop.sh

    ==============
    Usage: START
    ==============


    ./ora_db_start_stop.sh START ALL    

    OR

    ./ora_db_start_stop.sh START ONE_OR_MORE    


    ==============
    Usage: STOP
    ==============


    ./ora_db_start_stop.sh STOP ALL    

    OR

    ./ora_db_start_stop.sh STOP ONE_OR_MORE

    安装PDKSH之后

    ==============

    用法:START

    ./ora_db_start_stop.sh START ALL

    要么

    ./ora_db_start_stop.sh START ONE_OR_MORE

    ==============

    用法:停止

    ./ora_db_start_stop.sh STOP ALL

    要么

    ./ora_db_start_stop.sh STOP ONE_OR_MORE


    产生差异的原因是内部块是在原始Shell上下文中还是在子Shell中执行。您可以使用()和{}分组命令来控制它。就像您在更新中一样,使用临时文件在大多数情况下都可以使用,但是如果脚本快速运行两次,或者如果执行时没有清除文件,则将遇到问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/ksh
    flag=false
    echo"a
    b" | { while read x
    do    
         flag=true
    done }
    echo"flag = ${flag}"
    exit 0

    这可能有助于解决您在Linux ksh上遇到的问题。如果使用括号而不是括号,则将在其他ksh实现中获得Linux行为。


    我在本地Ubuntu Hardy系统上安装了" ksh"和" pdksh"。

    1
    2
    ii  ksh            93s+20071105-1 The real, AT&T version of the Korn shell
    ii  pdksh          5.2.14-21ubunt A public domain version of the Korn shell

    ksh具有您期望的"正确"行为,而pdksh没有。您可以检查本地Linux发行版的软件存储库中的"真实" ksh,而不使用pdksh。默认情况下," Real Unix"操作系统将安装Korn shell的AT&T版本,而不是pdksh,它们基于AT&T Unix(System V):-)。


    您必须待在ksh内吗?

    即使您使用相同的ksh,您仍然会调用各种外部命令(grep,ps,cat等),其中的一部分将具有不同的参数以及系统之间的不同输出。您要么必须考虑这些差异,要么使用每个差异的GNU版本来使它们相同。

    Perl编程语言最初是专门为克服此问题而设计的。
    它包括unix shell程序员希望从shell程序获得的所有功能,但是
    在每个Unix系统上都是相同的。您可能没有所有这些的最新版本
    系统,但是如果您需要安装某些软件,也许最好安装perl。


    zshemulate -L ksh选项一起使用时,脚本会提供正确的输出(true)。如果所有其他方法均失败,则您可能希望在Linux上尝试使用zsh


    我不知道有什么特定的选项可以强制ksh与特定的较旧版本兼容。就是说,也许您可??以在Linux机器上安装非常旧的ksh版本,并且其行为是否兼容?

    在AIX / HP-UX盒子上安装更新版本的amy shell可能会更容易,而只需迁移脚本以使用sh。我知道有适用于所有平台的bash版本。


    推荐阅读

      linux系统查版本命令?

      linux系统查版本命令?,系统,信息,名称,状态,设备,命令,软件,工具,版本,终端,l

      linux的安装软件命令?

      linux的安装软件命令?,软件,系统,名称,发行,官方网站,市场,官网,密码,网站,

      强大系统linux命令?

      强大系统linux命令?,系统,工作,地址,信息,命令,管理,名称,位置,目录,控制台,l

      linux脚本命令教学?

      linux脚本命令教学?,标准,数据,系统,脚本,代码,流程,官网,底部,命令,变量,lin

      linux安装dbe命令?

      linux安装dbe命令?,系统,电脑,通用,数据,环境,变动,在线,业务,信息,网站,LINU

      退出linux系统命令?

      退出linux系统命令?,系统,状态,工作,档案,命令,电脑,工具,基础,信息,时间,lin

      linux系统cmp命令?

      linux系统cmp命令?,系统,工作,标准,信息,命令,一致,目录,指令,功能,文件,请问

      linux系统命令行工具?

      linux系统命令行工具?,工具,系统,工作,状态,命令,地方,标准,信息,环境,基础,L

      linux系统刷新命令?

      linux系统刷新命令?,系统,工具,情况,最新,单位,工作,管理,信息,软件,服务,Lin

      linux系统sed命令?

      linux系统sed命令?,资料,系统,工作,跨行,代理,时间,简介,命令,文件,都会,Linu

      linux系统维护命令?

      linux系统维护命令?,系统,工作,信息,策略,发展,网络,时间,情况,工具,服务,系

      linux系统下载的命令?

      linux系统下载的命令?,系统,工作,管理,工具,软件,网络,信息,命令,目录,文件,l

      脚本linux上运行命令?

      脚本linux上运行命令?,工具,代码,时间,密码,系统,环境,名字,位置,第三,下来,t

      linux命令执行安装?

      linux命令执行安装?,软件,系统,管理,网站,官网,市场,中心,最新,灵活,工作,如

      linux系统安装命令集?

      linux系统安装命令集?,系统,软件,工作,工具,在线,信息,数据,官方网站,基础,

      linux看系统用户命令?

      linux看系统用户命令?,系统,信息,密码,命令,服务,名称,网络,情况,软件,工具,L

      linux修改脚本的命令?

      linux修改脚本的命令?,系统,密码,服务,工作,工具,环境,信息,百度,代码,脚本,

      dd命令安装linux?

      dd命令安装linux?,标准,设备,数据,系统,名称,位置,环境,信息,数字,情况,安卓L

      linux系统监听命令?

      linux系统监听命令?,网络,系统,工具,服务,数据,状态,名称,密码,短信,软件,lin

      终端命令行安装linux?

      终端命令行安装linux?,软件,系统,工具,终端,工作,状态,公司,官网,中心,时间,l