Linux와 Linux의 ksh 간의 비호환성을 극복하는 방법AIX/Solaris/HPUX에 설치되어 있습니까?

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

  •  09-06-2019
  •  | 
  •  

문제

저는 AIX, Solaris 및 HPUX에서 Linux로 수백 개의 ksh 스크립트가 포함된 시스템을 이식하는 과정에 참여하고 있습니다.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 상자에서 가장 먼저 하는 일 중 하나입니다...

내 로컬 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)를 기반으로 합니다. :-).

차이점이 있는 이유는 내부 블록이 원래 쉘 컨텍스트에서 실행되는지 아니면 하위 쉘에서 실행되는지입니다.() 및 {} 그룹화 명령을 사용하여 이를 제어할 수 있습니다.업데이트에서와 마찬가지로 임시 파일을 사용하면 대부분의 경우 작동하지만 스크립트가 두 번 빠르게 실행되거나 파일을 지우지 않고 실행하는 등의 경우 문제가 발생합니다.

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

이는 Linux ksh에서 발생한 문제를 해결하는 데 도움이 될 수 있습니다.중괄호 대신 괄호를 사용하면 다른 ksh 구현에서 Linux 동작을 얻게 됩니다.

echo " " 문제에 대한 또 다른 해결책은 다음과 같습니다.

단계:

  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비트인지 확인하고 올바른 패키지를 선택하세요)

  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가 특정 이전 버전과 호환되도록 하는 특정 옵션을 모르겠습니다.즉, Linux 상자에 아주 오래된 버전의 ksh를 설치하고 호환 가능한 방식으로 작동하도록 할 수 있습니까?

AIX/HP-UX 상자에 최신 버전의 amy 쉘을 설치하고 sh를 사용하도록 스크립트를 마이그레이션하는 것이 더 쉬울 수도 있습니다.모든 플랫폼에서 사용할 수 있는 bash 버전이 있다는 것을 알고 있습니다.

귀하의 스크립트는 다음과 같은 경우 올바른(true) 출력을 제공합니다. zsh 와 함께 사용됩니다. emulate -L ksh 옵션.다른 모든 방법이 실패하면 다음을 사용해 볼 수 있습니다. zsh 리눅스에서.

ksh 내에 머물러야 하나요?

동일한 ksh를 사용하더라도 여전히 모든 종류의 외부 명령(grep, ps, cat 등...)을 호출하게 되며 그 중 일부는 시스템마다 다른 매개변수와 다른 출력을 갖게 됩니다.이러한 차이점을 고려하거나 각 항목의 GNU 버전을 사용하여 동일하게 만들어야 합니다.

그만큼 프로그래밍 언어는 원래 이 문제를 극복하기 위해 정확하게 설계되었습니다.여기에는 He Shell 프로그램에서 원하는 Unix Shell 프로그래머가 원하는 모든 기능이 포함되어 있지만 모든 UNIX 시스템에서 동일합니다.모든 시스템에 최신 버전이 없을 수도 있지만 무언가를 설치 해야하는 경우 Perl을 설치하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top