Linux 上の ksh と Linux 上の ksh の間の非互換性を克服する方法AIX/Solaris/HPUX にインストールされていますか?

StackOverflow https://stackoverflow.com/questions/74372

  •  09-06-2019
  •  | 
  •  

質問

私は、数百の ksh スクリプトを含むシステムを AIX、Solaris、HPUX から Linux に移植するプロセスに携わっています。2 つのシステム上で ksh が動作する方法に次のような違いがあることがわかりました。

#!/bin/ksh
flag=false
echo "a\nb" | 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」という誤った (私の観点からは) 結果が得られます。

次の表は、問題が発生するシステムをまとめたものです。

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 でも正しく動作します。

#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
    flag=true
done < junk
echo "flag = ${flag}"
exit 0

以前に受け入れられた回答については jj33 に感謝します。

役に立ちましたか?

解決 2

社内の人からのアドバイスを受けて、コードに次の変更を加えることにしました。これにより、「本物の」 ksh (ksh88、ksh93) を使用しても、ksh クローン (pdksh、MSK ksh) を使用しても、同じ結果が得られます。これは bash でも正しく動作します。

#!/bin/ksh
echo "a\nb" > junk
flag=false
while read x
do
    flag=true
done < junk
echo "flag = ${flag}"
exit 0

以前に受け入れられた回答をしてくれた jj33 に感謝します。

他のヒント

Linux で pdksh を使用する代わりに、kornshell.org の「本物の」 ksh を使用してください。pdksh は、ksh をブラインドで再実装したものです。kornshell.org は、25 年ほど前に遡るオリジナルの korn シェルです (David Korn によって作成されたもの)。AIX と Solaris はオリジナルの ksh のバージョンを使用するため、kornshell.org バージョンは通常、機能とバグが完全です。SunOS/Solaris を使い始めたので、kornshell.org ksh のインストールは、通常、新しい Linux ボックスで最初に行うことの 1 つです...

ローカルの Ubuntu Hardy システムに「ksh」と「pdksh」をインストールしました。

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 はそうではありません。pdksh を使用する代わりに、ローカル Linux ディストリビューションのソフトウェア リポジトリで「本物の」 ksh を確認することもできます。「Real Unix」OS は、AT&T Unix (System V) をベースにしているため、デフォルトでは pdksh ではなく、AT&T バージョンの Korn シェルをインストールすることになります :-)。

違いの理由は、内部ブロックが元のシェル コンテキストで実行されるか、サブシェルで実行されるかです。() および {} グループ化コマンドを使用してこれを制御できる場合があります。更新時と同様に一時ファイルを使用すると、ほとんどの場合機能しますが、スクリプトが急速に 2 回実行された場合、またはファイルをクリアせずに実行された場合などに問題が発生します。

#!/bin/ksh
flag=false
echo "a\nb" | { while read x
do    
     flag=true
done }
echo "flag = ${flag}"
exit 0

これは、Linux ksh で発生していた問題の解決に役立つ可能性があります。中括弧の代わりに括弧を使用すると、他の ksh 実装で Linux の動作が得られます。

これは、エコー「 」問題の別の解決策です。

手順:

  1. ksh パッケージ名の検索

$ rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE}(%{ARCH})\n" | grep "ksh" ksh-20100621-19.el6_4.3(x86_64)

  1. kshをアンインストールする$ sudo yum remove ksh-20100621-19.el6_4.3.x86_64

  2. pdksh-5.2.14-37.el5_8.1.x86_64.rpm をダウンロードします (OS が 32 ビットか 64 ビットかを確認し、正しい pkg を選択してください)

  3. 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 インストール前の出力

$ ora_db_start_stop.sh
\n==============
Usage: START
==============\n\n
./ora_db_start_stop.sh START ALL    \n
OR \n
./ora_db_start_stop.sh START ONE_OR_MORE    \n
\n==============
Usage: STOP
==============\n\n
./ora_db_start_stop.sh STOP ALL    \n
OR \n
./ora_db_start_stop.sh STOP ONE_OR_MORE    \n\n

PDKSHのインストール後

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

使用法:始める

./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

ksh を特定の古いバージョンと互換性を持たせるための特定のオプションはわかりません。そうは言っても、非常に古いバージョンの ksh を Linux ボックスにインストールして、互換性のある方法で動作させることはできるでしょうか?

AIX/HP-UX ボックスに最新バージョンの amy シェルをインストールし、sh を使用するようにスクリプトを移行する方が簡単かもしれません。すべてのプラットフォームで利用できる bash のバージョンがあることは知っています。

スクリプトは、次の場合に正しい (真の) 出力を返します。 zsh と一緒に使用されます emulate -L ksh オプション。他のすべてが失敗した場合は、次の方法を試してみることをお勧めします zsh Linux 上で。

ksh内にとどまる必要がありますか?

同じ ksh を使用する場合でも、あらゆる種類の外部コマンド (grep、ps、cat など) を呼び出すことになりますが、その一部にはシステムごとに異なるパラメーターと異なる出力が含まれます。これらの違いを考慮するか、同じにするためにそれぞれの GNU バージョンを使用する必要があります。

パール プログラミング言語は元々、まさにこの問題を克服するために設計されました。UNIXシェルプログラマーがHEシェルプログラムに望むすべての機能が含まれていますが、すべてのUNIXシステムで同じです。これらすべてのシステムに最新バージョンがない場合がありますが、何かをインストールする必要がある場合は、Perlをインストールする方が良いかもしれません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top