glibc 버전을 구해 if 문에서 사용하여 glibc가 2.15 미만인지 확인하고 싶습니다.
그러나 문제는 ldd --version을 사용할 때 문자열로 출력된다는 것입니다. 비교를 위해 정수로 변환해야 합니다.
나는 이것을하곤했다
if [ "$(ldd --version | sed -n '1 p' | tr -cd '[:digit:]' | tail -c 3)" -lt 215 ]; then
소수점을 제거해야 하고 실제 버전 번호 비교를 제공할 수 없기 때문에 이는 실제로 좋지 않습니다. 또 다른 문제는 일부 glibc 버전에 소수점이 여러 개 있다는 것입니다(여기 참조).https://en.wikipedia.org/wiki/GNU_C_Library#Version_history) 이는 기존 비교가 엉망이 될 것임을 의미합니다.
따라서 이를 수행하려면 glibc 버전 전체를 정수로 변환하고 소수점이 여러 개인 경우에도 버전 번호를 정확하게 비교할 수 있어야 합니다.
어떤 아이디어가 있나요? 감사해요
답변1
ldd --version | sed 's/.* //;q' | awk -F. '{ if ($1 > 2 || ($1 == 2 && $2 >= 15)) { exit 0 } else {exit 1} }'
설명하다:
이 sed
명령은 출력의 첫 번째 줄을 가져와서 ldd --version
마지막 공백 앞의 모든 내용을 제거하고 종료합니다(따라서 숫자만 인쇄합니다).
필드 구분 기호로 설정된 플래그입니다 -F
.awk
.
첫 번째 숫자(점 앞)가 2보다 큰 경우또는첫 번째 숫자가 2이고 두 번째 숫자가 15 이상이면 awk
종료 상태는 "true"가 됩니다. 그렇지 않으면 가짜입니다.
다음과 같은 스크립트에서 사용할 수 있습니다 bash
.
if ldd --version | sed 's/.* //;q' | awk -F. '{ if ($1 > 2 || ($1 == 2 && $2 >= 15)) { exit 0 } else {exit 1} }' ; then
echo "Version is 2.15 or later"
else
echo "Version is too old."
fi
답변2
sort
버전 번호는 이를 활용하여 다음과 같이 작성할 수 있습니다.
if [ $(printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p') | sort -V | head -n 1) != 2.15 ]; then
# ...
fi
printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p')
ldd
버전 번호를 인쇄하고 두 개의 2.15
개별 라인에서 sort -V
오름차순으로 정렬 하고 head -n 1
첫 번째 라인을 인쇄합니다. 외부 명령 대체는 출력으로 대체되고 출력은 으로 대체됩니다 2.15
. 실행 본문이 실행됩니다.2.15
if
내 컴퓨터의 출력 예 ldd
2.21
:
% [ $(printf '%s\n2.15\n' $(ldd --version | sed -n '1s/.* //p') | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $(ldd --version | sed -n '1s/.* //p') || printf 'Version %s is equal or higher than 2.15\n' $(ldd --version | sed -n '1s/.* //p')
Version 2.21 is equal or higher than 2.15
버전 순서를 처리하는 이 메소드의 복잡성을 보여주기 위해 일부 하드코딩된 값이 포함된 출력 예:
% glibc_version=2.15
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.15 is equal or higher than 2.15
% glibc_version=2.16
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.16 is equal or higher than 2.15
% glibc_version=2.15.1
[ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.15.1 is equal or higher than 2.15
% glibc_version=2.14
% [ $(printf '%s\n2.15\n' $glibc_version | sort -V | head -n 1) != 2.15 ] && printf 'Version %s is lower than 2.15\n' $glibc_version || printf 'Version %s is equal or higher than 2.15\n' $glibc_version
Version 2.14 is lower than 2.15
답변3
버전 문자열을 정수로 변환하지 마세요. 문자열을 비교합니다.
이는 귀하의 사용 사례에 비해 약간 과잉이지만 여기에는 문자열 셸 함수의 보다 일반적인 버전이 있습니다. 그것은의 하위 집합을 따릅니다데비안 버전 비교 규칙:
- 버전은 블록별로 비교됩니다. 각 블록은 숫자로만 구성되거나 숫자가 포함되지 않은 최대 문자 시퀀스로 구성됩니다.
- 숫자가 아닌 시퀀스는 사전순으로 비교됩니다.
- 일련의 숫자는 소수 값을 기준으로 비교됩니다. 특히 앞에 오는 0은 관련이 없습니다.
마지막 비트는 1.01
같음으로 처리됩니다 1.1
. 이것은 아래에서 지불 1.1
하고 1.9
고려해야 할 가격입니다 1.10
.
이 코드에는 dash, bash, ksh 또는 zsh가 필요합니다. 다른 셸(예: BusyBox sh)과 함께 사용하려면 by 호출을 로 바꾸세요.[ "STRING1" \> "STRING2" ]
expr "aSTRING1" \> "aSTRING2"
version_ge () (
version1="$1" version2="$2"
while true; do
prefix1="${version1%%[0-9]*}" prefix2="${version2%%[0-9]*}"
if [ "$prefix1" \> "$prefix2" ]; then return 0; fi
if [ "$prefix2" \> "$prefix1" ]; then return 1; fi
version1="${version1#"$prefix1"}" version2="${version2#"$prefix2"}"
prefix1="${version1%%[!0-9]*}" prefix2="${version2%%[!0-9]*}"
version1="${version1#"$prefix1"}" version2="${version2#"$prefix2"}"
case "$prefix2" in
0*[!0]*) prefix2="${prefix2##"${prefix2%%[!0]*}"}";;
*[!0]*) :;;
*) return 0;;
esac
case "$prefix1" in
0*[!0]*) prefix1="${prefix1##"${prefix1%%[!0]*}"}";;
*[!0]*) :;;
*) return 1;;
esac
if [ "${#prefix1}" -gt "${#prefix2}" ]; then return 0; fi
if [ "${#prefix1}" -lt "${#prefix2}" ]; then return 1; fi
if [ "$prefix1" \> "$prefix2" ]; then return 0; fi
if [ "$prefix2" \> "$prefix1" ]; then return 1; fi
done
)