두 개의 서버가 있습니다. 하나는 기본 쉘 ksh가 있는 AIX이고 다른 하나는 기본 쉘 bash가 있는 RHEL입니다.
유사한 명령을 실행하지만 AIX 또는 Linux용으로 스크립트를 설치했습니다. 스크립트가 bash 서버에서 실행되지 않습니다. bash 및 ksh에서 스크립트를 실행하는 방법이 있습니까, 아니면 두 개의 다른 스크립트를 생성하는 가장 좋은 옵션이 있습니까?
#!/usr/bin/ksh
export OS=`uname -s`
echo "OS is "$OS"."
case $OS in
"AIX")
#run AIX commands;;
"Linux")
#run Linux commands;;
"*")
echo "Exiting. The OS type is not found.";;
esac
echo "Done."
exit 0
고쳐 쓰다
내가 실행해야 하는 명령은 각 서버의 사용자 계정에 대한 것입니다. 계정 잠금 해제의 예. AIX /usr/bin/chuser account_locked=false $USERNAME
Linux /usr/bin/passwd -u $사용자 이름
추가 조사를 통해 AIX의 셸 위치는 /usr/bin/sh에 있는 반면 Redhat의 셸 위치는 /bin/sh에 있음을 발견했습니다.
"uname"의 결과를 기반으로 shebang을 정의할 수 있나요?
답변1
가장 쉬운 방법은 두 시스템 모두에서 동일한 셸을 사용하는 것입니다. 쉘이 사전 설치되어 제공된다고 해서(스크립트에 대한 "기본 쉘" 같은 것은 없으며, 쉘은 shebang 줄에서 말하는 대로임) 다른 쉘을 설치할 수 없다는 의미는 아닙니다. AIX에 bash를 설치할 수 있습니다(공구 상자, 예를 들어) 또는 Linux의 경우 ksh93(배포판의 패키지 관리자 사용: 패키지 설치 ksh
).
ksh를 선택하는 경우 /usr/bin/ksh
AIX에서는 ksh88입니다. Linux에는 ksh88 버전이 없으며 /usr/bin/ksh93
AIX에서 사용 가능한 ksh93 버전만 있습니다.
두 시스템의 동일한 위치에 동일한 쉘을 설치하면(심볼릭 링크가 가능함) shebang 라인에서 동일한 경로를 사용할 수 있으면 더 쉬울 것입니다. 동일한 위치를 갖는 것이 너무 어려운 경우 두 시스템 모두에 있는지 #!/usr/bin/env bash
확인하는 한 유사한 것을 사용할 수 있습니다 . 이는 루트 액세스 권한이 없기 때문에 홈 디렉터리에 bash 또는 ksh를 설치해야 하는 경우 유용할 수 있습니다.bash
PATH
실제로 두 시스템에 동일한 쉘을 설치할 수 없는 경우(아마도 사람들의 삶을 복잡하게 만들지만 뒤집기에는 너무 뿌리 깊은 어리석은 규정 준수 규칙이 있기 때문일 수 있음) 몇 가지 가능성이 있습니다.
#!/bin/sh
시스템에서 제공하는 크로스 와이어 및 프로그램 으로 사용하십시오 . 모든 최신 UNIX 시스템은 다음을 제공합니다.POSIX 쉘처럼/bin/sh
. AIX에서는/bin/sh
ksh88입니다. Red Hat에서는/bin/sh
bash입니다(로 호출하면 약간 다르게 동작함sh
). 일부 다른 운영 체제(예: 많은 Linux 배포판)에서는/bin/sh
POSIX보다 더 많은 기능을 갖고 있지 않을 수 있는 작은 셸입니다.더 나은 쉘을 찾아 실행하는 일부 상용구 코드로 스크립트를 시작하십시오.
#!/bin/sh if [ -n "$BASH" ]; then … bash compatibility code … elif type whence >/dev/null 2>/dev/null; then … ksh compatibility code … elif type ksh93 >/dev/null 2>/dev/null; then exec ksh93 "$0" "$@" elif type ksh >/dev/null 2>/dev/null; then exec ksh "$0" "$@" elif type mksh >/dev/null 2>/dev/null; then exec mksh "$0" "$@" elif type bash >/dev/null 2>/dev/null; then exec bash "$0" "$@" else echo 1>&2 "Cannot find ksh or bash, aborting" exit 125 fi
두 경우 모두 ksh88과 bash의 교차점은 POSIX 이상의 유용한 기능을 제공하지만 일부 호환성 코드가 필요할 수 있습니다. 특히:
- ksh88에서 배열 할당 사용을
set -A
참조하세요.다양한 ksh 환경의 할당 변수 - 지역 변수는 으로 선언됩니다
typeset
. - Ksh88 아니요
${VAR/PATTERN/REPLACEMENT}
,$'…'
또는FIGNORE
. 그렇습니다[[ … ]]
. @(…)
Bash에서 ksh 및 기타 ksh 확장 모드를 활성화 하려면 를 실행하세요shopt -s extglob
.
답변2
두 가지 별도 버전의 스크립트를 사용하는 것이 더 쉬울 수도 있습니다. 너무 짧기 때문에 jw013이 제안한 대로 두 형식 간의 차이점을 처리하기 위해 추가 코드를 추가하는 것은 가치가 없을 것입니다. 반면에 더 큰 스크립트가 있는 경우 하나의 스크립트를 사용하고 실행 위치에 따라 다른 명령을 실행하는 것이 더 쉬울 수 있습니다.
답변3
비슷한 요구 사항이 있습니다. AIX 5.3에서 ksh93을 사용하여 연관 배열을 지원해야 합니다. 그래서 ksh93을 사용하여 두 번째 인스턴스를 시작하는 스크립트를 설정했습니다. 또한 반복해서 다시 생성되는 것을 방지하기 위해 보호 기능도 추가했습니다.
#!/bin/ksh
scr=$0
safe=$1
echo "Check OS to determine if ksh93 is needed..."
if ( `typeset -A testvar > /dev/null 2>&1` ); then
echo "Associative array functions supported."
else
echo "Associative array functions NOT supported. Starting second instance with ksh93..."
if [ "$safe" -eq 1 ]; then
echo "SECOND INSTANCE ALREADY STARTED!"
exit 1
else
echo "BEGIN SECOND INSTANCE USING KSH93"
/bin/ksh93 $scr 1
exit 0
fi
fi
답변4
Giles의 답변은 (IMHO) 훌륭합니다(언제나 그렇듯이). 하지만 선택하지도 않았고 투표도 하지 않았기 때문에 너무 복잡하다고 생각했을 수도 있습니다. 따라서 도움이 될 수도 있고 그렇지 않을 수도 있는 몇 가지 (간단한) 사항이 있으며, 시간이 지남에 따라 유지 관리해야 하는 대규모 스크립트로 인해 문제가 발생할 수 있는 두 개의 개별 스크립트를 유지 관리하는 것을 피하는 데 도움이 될 수 있습니다.
1) bash
대화식 사용을 위한 기본 쉘이 아니더라도 AIX 시스템에 설치되어 있을 수 있습니다. (제가 사용하고 있는 AIX 머신에는 이 기능이 bash
설치되어 있지만 시스템 관리자가 추가했는지는 모르겠습니다. 우리 시스템 관리자는 모두 ksh
마약 중독자이기 때문에 그런 식으로 설치한 것 같습니다.) 저는 기꺼이 그렇게 할 것입니다. RHEL 시스템에 베팅했습니다 ksh
. 이미 설치되어 있습니다. 두 시스템에서 동일한 쉘을 사용할 수 있으면 절약할 수 있으므로 이것을 확인하십시오.많은문제.
2) 쉘이 어디에 설치될지 모르는 경우, 쉘 경로를 shebang 라인에 직접 입력하지 마십시오. 대신 아래와 같이 경로 env
와 셸 실행 파일 이름을 입력하세요.
#!/usr/bin/env bash
이것~해야 한다두 컴퓨터 모두에서 작동하지만 확실히 알아보려면 테스트해야 합니다. ( env
또는 대부분의 사물의 입장보다 의 입장이 더 표준적이라고 주장합니다 .)bash
두 시스템 모두에서 동일한 셸을 사용하면 문제가 해결될 수 있습니다. 하지만 그렇지 않다면...
3) 소스 코드의 플랫폼별 코드를 기본 스크립트 내의 함수로 나눌 수 있습니다. 즉, 스크립트에위치AIX에서 실행하는지 RHEL에서 실행하는지에 따라 상황이 다르게 작동하므로 플랫폼을 다시 확인할 필요가 없습니다. 한 번만 수행하면 적절한 기능을 얻을 수 있습니다.
case $OS in
"AIX")
source aix_functions;;
"Linux")
source redhat_functions;;
"*")
echo "Exiting. The OS type is not found.";;
esac
case
이제 플랫폼을 구별하기 위해 추가 문을 사용하지 않고도 스크립트 전체에서 얻을 수 있는 모든 기능을 사용할 수 있습니다 .
do_something_platform_specific "$SOME_ARGUMENT" "$SOME_OTHER_ARGUMENT"