5

私は、数百の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およびHPUXkshはksh88のバリアントです。
  • Linuxでは、kshはパブリックドメインksh(pdksh)です。
  • AIXでは、SolarisとHPUXのdtkshとksh93(インストールしている場所)はkshと整合性があります
  • 私がアクセスできるWindowsNTシステム: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に感謝します。

4

8 に答える 8

7

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つです...

于 2008-09-16T16:51:28.687 に答える
3

私の会社の人々からのアドバイスの後、コードに次の変更を加えることにしました。これにより、「実際の」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 に感謝します。

于 2008-09-18T18:22:36.983 に答える
1

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

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

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

于 2008-10-31T23:05:01.257 に答える
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 は、デフォルトで、pdksh ではなく AT&T バージョンの Korn シェルをインストールします。これは、AT&T Unix (System V) に基づいているためです :-)。

于 2008-09-16T17:25:08.370 に答える
1

エコー "\n" 問題の別の解決策は次のとおりです。

手順:

  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 をダウンロードします (32 ビットまたは 64 ビットの OS を確認し、正しい 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

于 2014-03-20T15:37:23.310 に答える
0

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

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

于 2008-09-16T16:48:48.927 に答える
0

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

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

Perlプログラミング言語は、もともとこの問題を解決するために設計されました。Unix シェル プログラマーがシェル プログラムに必要とするすべての機能が含まれていますが、すべての Unix システムで同じです。これらすべてのシステムで最新バージョンを使用しているわけではありませんが、何かをインストールする必要がある場合は、perl をインストールしたほうがよいでしょう。

于 2008-09-16T20:46:27.013 に答える
0

zshをオプションとともに使用すると、スクリプトは正しい (真の) 出力を提供しemulate -L kshます。他のすべてが失敗した場合はzsh、Linux で使用してみてください。

于 2008-09-16T17:03:08.313 に答える