hh:mm:ss 형식 변수를 비교하는 다음 스크립트를 만들었습니다.
#!/bin/sh
lag=00:00:00
MAX_LAG=00:05:00
echo $lag
echo $MAX_LAG
if [ "$lag" \< "$MAX_LAG" ]
##if [ "$lag" -lt "$MAX_LAG" ]
##if [ "$lag" -lt "$MAX_LAG" ]
then
echo "No LAG found."
else
echo "LAG more than $MAX_LAG was found."
fi
Linux 상자에서 실행할 때 스크립트가 올바른 출력을 제공합니다.
[test@sandboxtest02 ~]$ ./testhh.sh
00:00:00
00:05:00
No LAG found.
하지만 Solaris 상자에서 동일한 스크립트를 실행하면 스크립트에서 오류가 발생합니다.
% sh test.sh
00:00:00
00:05:00
test.sh: test: unknown operator <
솔라리스 상자에서 무엇을 변경해야 하는지 제안해 주시겠습니까?
답변1
<
표준 연산자가 아님test
/[..]
(아래 인용문 참조). Bash, Dash, busybox 등에서는 지원되는 것 같지만 Zsh에서는 지원되지 않는 것 같습니다(Ksh의 다른 버전에 대해서는 잘 모르겠습니다). Bash, ksh 및 Zsh도 지원됩니다(이스케이프 필요 없음). 이들 중 하나를 지원하는 쉘을 찾아서 사용해야 합니다.[[ str1 < str2 ]]
<
(알아채다Solaris 10 및 이전 버전에는 POSIX 이전 버전도 있었습니다./bin/sh
, 이는 어떤 의미에서도 표준이 아니기 때문에 중요하지 않습니다. )
새로 발명되었거나 KornShell에서 나온 일부 추가 기본 명령은 조건부 명령의 일부로 초기 제안에 나타났습니다([[]]): s1>s2, s1<s2,...다음으로 전달되지 않습니다.시험조건부 명령이 아직 포함되지 않았기 때문에 쉘에서 제거될 때의 유틸리티시험역사적 구현에 내장된 유틸리티쉿유용.
답변2
Solaris-sh에서 작동하도록 몇 가지 조정 사항이 있습니다. 제가 한 방법은 다음과 같습니다.
#!/bin/sh
lag=00:06:00
MAX_LAG=00:05:00
IFS=:
set -f
set -- $lag
lagtotal=`expr 3600 * $1 + 60 * $2 + $3`
set -- $MAX_LAG
maxlag=`expr 3600 * $1 + 60 * $2 + $3`
if [ "$lagtotal" -lt "$maxlag" ]
then
echo "No LAG found."
else
echo "LAG more than $MAX_LAG was found."
fi
('LAG'와 비교하는 것보다 엄격하다는 점에 유의하세요.더비교하다...")
답변3
POSIX 도구 상자에서 문자열을 비교하는 데 expr
사용할 awk
수 있습니다.
둘 다 비교에 사용되지만 strcoll()
( sort
:locale과 동일한 정렬 순서) 로케일을 C로 설정하여 strcmp()
비교 유형을 얻을 수 있습니다. HH:MM:SS와 같은 경우에는 어쨌든 중요하지 않습니다.
if expr "$time1" '<' "$time2" > /dev/null; then
printf '%s\n' "$time1 was before $time2"
fi
이제 이는 HH:MM:SS의 경우에는 중요하지 않지만 일반적인 경우 expr
피연산자가 십진 정수이면 숫자 비교가 수행되고, 그렇지 않으면 문자열 비교가 수행됩니다. 이는 예 를 들어 짝수 2
보다 작은 것으로 취급되거나 그렇지 않은 것으로 간주된다는 것을 의미합니다.10
strcmp()
strcoll()
또한 expr
피연산자가 연산자이면 실패합니다 expr
.
$ x=+ y=-; expr "$x" '<' "$y"
expr: syntax error
피연산자에 접두사를 추가하여 피연산자가 숫자나 연산자로 처리되는 것을 방지하면 두 가지 문제를 모두 해결할 수 있습니다.
expr "x $x" '<' "x $y"
의 경우 awk
에도 비슷한 문제가 있습니다. 다음을 수행해야 합니다.
awk 'BEGIN{exit(!(""ARGV[1] < ""ARGV[2]))}' "$x" "$y"
비교가 숫자 비교가 아닌 문자열 비교인지 확인하십시오.
다음과 같은 도우미 기능을 사용할 수 있습니다.
compare() {
expr "x $1" "$2" "x $3"
}
또는:
compare() {
awk 'BEGIN{exit(!(""ARGV[1] '"$2"' ""ARGV[2]))}' "$1" "$3"
}
다음과 같이 사용됩니다.
if compare "$time1" '<' "$time2"; then
printf '%s\n' "$time1 was before $time2"
fi
/usr/xpg4/bin
어쨌든, 솔라리스에서는 늘 그렇듯, 이전 버전인지 확인해야 합니다. /bin
그렇지 /usr/bin
않으면 $PATH
쓸모없는 비표준 유틸리티를 사용하게 될 것입니다. 특히, /bin/awk
Solaris에서는 위의 코드가 작동하지 않습니다. 이것은 1970년대의 것입니다. 아니요 ARGV
.
#!/bin/sh
같은 이유로 she-bang에 사용하고 싶지 않습니다 . Solaris의 Standard/POSIX는 sh
다음과 같습니다 /usr/xpg4/bin/sh
(Solaris 11에서는 /bin/sh
Bourne 셸에서 ksh93으로 변경되어 POSIX와 더욱 호환됩니다. 또한 /usr/xpg4/bin/sh
많은 적합성 버그가 있다는 점에 유의하세요).
답변4
최근 Solaris 시스템[1]에서는 /bin/sh
그렇습니다. ksh93
따라서 다음을 수행해야 합니다:
if [[ "$lag" < "$MAX_LAG" ]]; then ..
[[ .. ]]
내부적으로 사용되는 경우 이중 괄호에 유의 하세요 [[ .. ]]
.<
사전 편찬의 비교에서는 유사한 문자열 ksh
에 대해 작동합니다 .HH:MM:SS
쉘이 실제로 이것을 지원하지 않으면 cannon을 사용할 수 있습니다.
trim(){ ifs=IFS; IFS=:; v=$1; set -- $2; eval "$v=$1$2$3"; IFS=$ifs; }
trim a "$lag"
trim b "$MAX_LAG"
if [ "$a" -lt "$b" ]; then ..
[1] /bin/sh
솔라리스에서는ksh93
솔라리스 11부터 시작.