#!/bin/sh
CONFIG_DIR="/var/opt/SUNWldm/"
read option
if [ $option -eq 9 ]; then
ret=1
elif [ -e ${CONFIG_DIR}file.xml.${option} ]; then
echo "TRUE"
fi
옵션 목록을 표시하기 위해 while 루프에서 위 코드를 사용했습니다. 불행하게도 진술에 문제가 있습니다 elfi
.
에서:초보자라면-e는 파일이 존재하면 true를 반환합니다.
구문을 다시 확인하고 디버그 모드( set -x
스크립트 시작 부분에 설정) 에서 스크립트를 실행했는데 if
인라인에 표시된 것처럼 대체가 올바르게 수행되었음을 확인할 수 있었습니다.
+ [ 201301271355 -eq 9 ]
+ [ -e /var/opt/SUNWldm/file.xml.201301271355 ]
./ldm_recover.sh: test: argument expected
지금까지 찾아보았으나 실패 원인을 찾지 못했는데, 제가 뭘 잘못하고 있는지 아시나요?
답변1
Bourne 쉘은 골동품입니다. Solaris 버전 -e
에는 Bourne 쉘의 라이프사이클 후반에 도입되었으며 POSIX에서 소중히 여기는 내장 함수의 연산자 가 없습니다 .test
[
-f
해결 방법으로 일반 파일이 존재하는지 또는 -r
읽을 수 없는 파일에 관심이 없는지 테스트하는 데 사용할 수 있습니다 .
더 나은 방법은 POSIX 쉘로 변경하거나 구입하는 것 #!/bin/sh
입니다 #!/usr/xpg4/bin/sh
.#!/bin/ksh
이는 [ $option -eq 9 ]
아마도 잘못된 것일 수 있습니다. -eq
숫자 비교 연산자이지만 $option
실제로는 숫자가 아닙니다. 날짜입니다. 32비트 시스템에서 201301271355
숫자로 해석 되면 모듈로 2 32 입니다. 공교롭게도 21세기에는 0 모듈로 2 32 에 매우 가까운 날짜가 없지만 이에 의존하는 것은 매우 취약합니다. 대신 이것을 만드십시오 [ "$option" = 9 ]
.
일반적인 쉘 프로그래밍 원칙으로,변수 및 명령 대체에는 항상 큰따옴표를 사용하십시오.: "$foo"
, "$(foo)"
. 이렇게 하지 않으면 쉘은 결과를 각 공백 문자로 분할하고 각 결과 단어를 파일 이름 와일드카드 패턴으로 처리합니다. 따라서 $foo
값에 공백이나 가 포함되지 않은 foo
경우에만 보호되지 않는 것이 안전합니다 \[?*
. 주의해서 진행하고 항상 큰따옴표를 사용하십시오(분할 및 패턴 일치를 수행할 계획이 없는 한).
아니면 Bourne으로 포팅되지 않은 ksh 추가 기능입니까 ? 나는 모른다.
답변2
음, 생각보다 쉽습니다:
-e
the 연산자는 if
bourne 쉘(sh)에는 정의되어 있지 않고, bourne Again 쉘(bash)에서만 정의되어 있는 것 같습니다 .
나는 if [ -e ...
로 교체했고 if [ -r ...
작동합니다.