Как преодолеть несовместимость между 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 — это оригинальная оболочка Korn, созданная примерно 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.В ОС «Настоящий Unix» по умолчанию будет установлена ​​версия оболочки Korn AT&T, а не pdksh, поскольку они основаны на AT&T Unix (System 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. удалить КШ$ 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-битную ОС и выберите правильный пакет)

  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

После установки ПДКШ

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

Использование:НАЧИНАТЬ

./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 на компьютеры AIX/HP-UX и просто перенести свои сценарии на использование sh.Я знаю, что существуют версии bash для всех платформ.

Ваш скрипт дает правильный (истинный) вывод, когда zsh используется с emulate -L ksh вариант.Если все остальное не помогло, вы можете попробовать использовать zsh на Линуксе.

Вам обязательно оставаться в пределах КШ?

Даже если вы используете один и тот же ksh, вы все равно будете вызывать все виды внешних команд (grep, ps, cat и т. д.), часть из них будет иметь разные параметры и разные выходные данные от системы к системе.Либо вам придется принять во внимание эти различия, либо использовать версию GNU каждого из них, чтобы сделать вещи одинаковыми.

А Перл Язык программирования изначально был разработан именно для решения этой проблемы.Он включает в себя все функции, которые программист Unix Shell хотел бы от программы He Shell, но он одинаково в каждой системе UNIX.Возможно, у вас не будет последней версии во всех этих системах, но если вам нужно что -то установить, возможно, лучше установить Perl.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top