ksh 버전을 안전하게 얻는 방법은 무엇입니까?

ksh 버전을 안전하게 얻는 방법은 무엇입니까?

내가 어떻게 할 수있는안전하게ksh 스크립트에서 ksh 버전을 얻으시겠습니까?

나는 가지고있다다음 해결책을 보았습니다.:

  1. ksh --version
  2. echo ${.sh.version}
  3. echo $KSH_VERSION

이것들은 모두 올바른 상황에서 잘 작동합니다. 그러나 내가 걱정하는 것은 불완전함이다.

특히, 제가 작업하고 있는 몇몇 기계에는 제 목적에 맞는 기능이 심각하게 부족한 이전 버전의 ksh가 설치되어 있습니다. 어쨌든, 내가 (프로그래밍 방식으로) 버전을 확인하려는 이유는 ksh 버전이 약한 버전 중 하나인지 확인하기 위한 것입니다. 그렇다면 덜 좋은 코드로 분기를 실행하고 싶습니다.

그러나 문제의 컴퓨터에서는 쉘의 무능력이 버전 확인까지 확장됩니다.

  • 시도하면 ksh --version아무것도 인쇄되지 않고 새 인스턴스가 열립니다 ksh!
  • 시도하면 echo ${.sh.version}구문 ksh오류로 처리되어 작동하지 않습니다 2> /dev/null.

    $ echo ${.sh.version} 2> /dev/null  
    ksh: ${.sh.version}: bad substitution
    
  • 물론 echo $KSH_VERSION잘 작동하는 것 같습니다. 충돌하지 않는다는 뜻입니다. 비록 이 컴퓨터에서는 비어 있지만요. 또한, 나는 보았다어딘가에KSH_VERSION설정으로만 pdksh.

질문:

  • 프로그래밍 방식으로 버전을 안전하게 확인하는 방법은 무엇입니까 ksh? 내 목적상 실제 버전 번호가 무엇인지는 중요하지 않으며 오래된 버전인지 여부만 중요합니다 ksh.
  • 충분 하다 $KSH_VERSION? 내 말은, 비어 있으면 ksh오래된 버전임에 틀림없다는 건가요? 최신 버전에서도 설정이 불가능할 수 있다는 다른 포럼의 내용이 맞습니까 ksh?
  • 이거 확인할 수 있는 방법 없나요?

답변1

KSH_VERSION93t 이전 버전에서는 구현되지 않았습니다 ksh93. mksh, pdksh, 에 설정됩니다 lksh. 따라서 버전을 확인하려면 ksh다음 단계를 시도해 보세요.

이를 염두에 두고 나는 다음을 수행할 것입니다.

case "$KSH_VERSION" in
  (*MIRBSD*|*PD*|*LEGACY*) printf '%s\n' "$KSH_VERSION" ;;
  (*) [ -z "$ERRNO" ] && printf '%s\n' "${.sh.version}" || echo ksh88/86 ;;
esac

답변2

.sh.versionATT ksh 93의 첫 번째 버전부터 있었던 것 같습니다 . pdksh 또는 mksh에서는 사용할 수 없습니다. ksh93이 아닌 셸의 구문 오류 이므로 ${.sh.version}해당 테스트를 하위 셸로 래핑하고 eval.

_sh_version=$(eval 'echo "${.sh.version}"' 2>/dev/null) 2>/dev/null
case $_sh_version in
  '') echo "This isn't ATT ksh93";;
esac

KSH_VERSION원래 공개 도메인 ksh 클론(pdksh)에 등장했으며 2008년 ksh93t를 통해 실제 Korn 셸에 추가되었습니다.

버전 번호를 테스트해서는 안 되며, 문제를 일으키는 특정 기능을 테스트해야 합니다. 대부분의 기능은 서브셸에서 특정 구성을 시도하고 오류가 발생하는지 확인하여 테스트할 수 있습니다.

답변3

"실제" ksh버전(예: AT&T 기반)의 경우 다음을 사용합니다.

strings /bin/ksh | grep Version | tail -2 

내가 얻는 다양한 결과는 다음과 같습니다.

원본 ksh:

@(#)Version M-11/16/88i

dtksh;

@(#)Version 12/28/93
Version not defined

최신 ksh93:

@(#)$Id: Version AJM 93u+ 2012-08-01 $

pdksh/ msh kshclone 및 최신 AT&T 버전 의 경우 ksh다음이 유효합니다.

$ mksh -c 'echo $KSH_VERSION'
@(#)MIRBSD KSH R50 2015/04/19

편집하다:

테스트 중인 ksh 바이너리의 경로를 아는 것이 아니라 스크립트 내에서 이 작업을 수행하는 방법에 대해 질문하고 있다는 점을 간과했습니다.

ksh버전이 지원하는 기능이 아닌 를 사용하기를 정말로 원한다고 가정하면 strings최소한 Linux 및 Solaris에서 작동하는 명령만 사용하여 이를 수행하는 방법은 다음과 같습니다.

echo $(for i in $(find /proc/$$ ! -type d ! -name "pagemap" | 
  grep -v "/path/" | grep -v "/fd/" ) ; do
  strings $i | egrep "([V]ersion|[K]SH_VERSION).*[0-9]" | sort -u
done 2>/dev/null)

/proc이 방법은 설치되지 않을 수 있고 확실히 다른 약점도 있기 때문에 신뢰할 수 없습니다 . 다른 Unix 운영 체제에서는 테스트되지 않았습니다.

답변4

CTRL+ ALT+V

또는

ESC, CTRL+V

이는 일반적으로 사용 중인 KSH 버전을 대화식으로 결정하는 데 매우 안정적인 것으로 입증되었지만 스크립팅은 더 어려운 것으로 입증되었습니다.

관련 정보