كيفية التغلب على عدم التوافق بين ksh على Linux مقابل.التي تم تثبيتها على AIX/Solaris/HPUX؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

أنا منخرط في عملية نقل نظام يحتوي على عدة مئات من نصوص ksh من AIX وSolaris وHPUX إلى Linux.لقد واجهت الفرق التالي في الطريقة التي يتصرف بها 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".

أسئلتي هي:

  • هل هناك متغير بيئة يمكنني تعيينه للحصول على KSH من Linux يتصرف مثل نظام التشغيل الآخر؟الإخفاق في ذلك:
  • هل هناك خيار على نظام Linux ksh للحصول على السلوك المطلوب؟الإخفاق في ذلك:
  • هل يتوفر تطبيق ksh لنظام التشغيل Linux بالسلوك المطلوب؟

الملاحظات الأخرى:

  • في 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 على الإجابة المقبولة السابقة.

نصائح أخرى

بدلاً من استخدام pdksh على نظام التشغيل Linux، استخدم ksh "الحقيقي" من kornshell.org.pdksh هو إعادة تنفيذ أعمى لـ ksh.kornshell.org هي قذيفة كورن الأصلية التي يعود تاريخها إلى 25 عامًا أو نحو ذلك (التي كتبها ديفيد كورن).يستخدم AIX وSolaris إصدارات من ksh الأصلي، وبالتالي فإن إصدار kornshell.org عادةً ما يكون مكتملًا بالميزات والأخطاء.بعد أن أتقنت استخدام SunOS/Solaris، عادةً ما يكون تثبيت kornshell.org ksh من أول الأشياء التي أقوم بها على جهاز Linux جديد...

لقد قمت بتثبيت "ksh" و"pdksh" على نظام Ubuntu Hardy المحلي الخاص بي.

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" بتثبيت إصدار AT&T من Korn Shell، بدلاً من pdksh، بشكل افتراضي، والذي يعتمد على AT&T Unix (النظام V) :-).

سبب الاختلافات هو ما إذا كانت الكتلة الداخلية قد تم تنفيذها في سياق الصدفة الأصلي أو في غلاف فرعي.قد تتمكن من التحكم في ذلك باستخدام أوامر التجميع () و{}.إن استخدام ملف مؤقت، كما تفعل في التحديث الخاص بك، سيعمل في معظم الأوقات ولكنه سيواجه مشكلات إذا تم تشغيل البرنامج النصي مرتين بسرعة، أو إذا تم تنفيذه دون مسح الملف، وما إلى ذلك.

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

قد يساعد ذلك في حل المشكلة التي كنت تواجهها في Linux ksh.إذا استخدمت الأقواس بدلاً من الأقواس، فستحصل على سلوك Linux في تطبيقات ksh الأخرى.

إليك الحل الآخر لمشكلة الصدى " ".

خطوات:

  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 بت واختيار 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 الخاص بك، وجعله يتصرف بطريقة متوافقة؟

قد يكون من الأسهل تثبيت إصدار أكثر حداثة من amy Shell على صناديق AIX/HP-UX، وما عليك سوى ترحيل البرامج النصية الخاصة بك لاستخدام sh.أعلم أن هناك إصدارات من bash متاحة لجميع الأنظمة الأساسية.

يعطي البرنامج النصي الخاص بك الإخراج الصحيح (الحقيقي) عندما zsh يستخدم مع emulate -L ksh خيار.إذا فشل كل شيء آخر قد ترغب في محاولة استخدام zsh على لينكس.

هل يجب عليك البقاء في حدود ksh؟

حتى لو كنت تستخدم نفس ksh، فسوف تستمر في استدعاء جميع أنواع الأوامر الخارجية (grep، ps، cat، إلخ...) وسيكون لجزء منها معلمات مختلفة ومخرجات مختلفة من نظام إلى آخر.إما أنه سيتعين عليك أن تأخذ هذه الاختلافات في الاعتبار أو تستخدم إصدار GNU لكل واحد منهم لجعل الأمور متشابهة.

ال بيرل تم تصميم لغة البرمجة في الأصل خصيصًا للتغلب على هذه المشكلة.ويشمل جميع الميزات التي يريدها مبرمج Unix Shell من برنامج SHELL ، ولكنه هو نفسه في كل نظام UNIX.قد لا يكون لديك أحدث إصدار في جميع هذه الأنظمة ، ولكن إذا كنت بحاجة إلى تثبيت شيء ما ، فربما يكون من الأفضل تثبيت Perl.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top