패키지가 APT에 설치되어 있는지 테스트


10

패키지가 설치되어 있으면 쉘 스크립트 메소드를 테스트 /보고하고 싶습니다. 논리 흐름을 설정하기 위해 세부 정보가 필요하지 않고 부울 리턴 만 필요합니다. 나는 보았다 패키지가 설치되어있는 경우 찾기dpkg반환 복잡한 출력 및 형식 변경이 패키지는 데비안 저장소에 또는 우분투 PPA에 있는지 여부에 따라 달라집니다.

나는 그것이 apt-cache꽤 잘 작동 한다는 것을 알았고이 방법을 생각해 냈습니다.

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

누구나 더 간단하거나 직접적인 방법을 알고 있습니까?

답변:


12

dpkg-query 링크 된 게시물에서와 같이 사용 가능한 Python 라이브러리를 사용하여 이러한 스크립팅 컨텍스트에서 APT 시스템에 직접 바인딩하는 것을 제외하고는 작업에 가장 적합한 도구 인 것처럼 보입니다.

dpkg-query:

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

0패키지가 설치된 경우 true ( 셸 스크립트의 종료 상태 1)를 반환하고, 그렇지 않으면 false (종료 상태 )를 반환합니다.

  • -W"표시"를 의미 dpkg-query합니다 ( 요청 된 조치가 있어야 함).
  • -f 출력 형식을 변경합니다.
  • db:Status-abbrev 패키지 상태의 짧은 형식입니다.
  • 2>/dev/nulldpkg-query유효하지 않은 패키지 이름이 제공되면 침묵 합니다. 이 문제를 처리하는 방법은 사례마다 다를 수 있습니다.
  • grep -q 일치하는 것이 있으면 true를, 그렇지 않으면 false를 반환합니다.

자주 사용하는 경우 간단한 기능으로 만들 수 있습니다.

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

아니면 그냥

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi

이것은 의심의 여지없이 정확하지만 dpkg-query -l "$package" | grep -q ^.i일반적으로 충분하고 기억하기 쉽다는 것을 알았습니다 .
phogg

1
@phogg : 그렇습니다. 스크립트에 살지 여부에 달려 있습니다. 또한 dpkg-query -l출력은 단지 사용자 프리젠 테이션 모드이기 때문에 결석으로 설정되지 않으므로 프리젠 테이션이 변경되면 이러한 스크립트가 중단 될 수 있습니다.
Daniel Andersson

@ 다니엘. 리턴 코드 접근 방식이 마음에 듭니다. 코드에 대한 자세한 내용은 내 답변을 참조하십시오.
tahoar

10.04에서 db : Status-abbrev 형식 옵션이 존재하지 않는 것 같습니다 dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'.
scottynomad

1

다음과 같은 세 가지 패키지에 대한 Daniel의 제안을 테스트했습니다.

  1. 네이티브 데비안 저장소 패키지가 설치되지 않았습니다 :

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. 호스트에 등록되어 설치된 PPA 패키지 :

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. 호스트에 등록되었지만 설치되지 않은 PPA 패키지 :

    ~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce
    ~$ echo $?
    0
    ~$ sudo apt-get remove domy-ce
    [sudo] password for user: 
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    Package domy-ce is not installed, so not removed
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    

접근 방식이 마음에 들지만 PPA 패키지로 리턴 코드를 신뢰할 수없는 것 같습니다. 그것의 부족으로, 나는 apt-cache policy명령 의 반환을 파싱하는 것을 고수 할 것이라고 생각합니다 .


글쎄, 귀하의 코드 예제는 내가해야한다고 말한 것이 아니지만 grep붙여 넣기 에서 부분을 놓친 것 같습니다 . 실제로 문제를 재현 할 수는 없지만 코드 예제가 현재 불완전하기 때문일 수 있으므로 수정하십시오. 데비안 또는 우분투를 실행합니까?
Daniel Andersson

우분투 10.04를 사용하고 있습니다 (PPA는 데비안을 지원하지 않습니까?). 내 코드는 1) dkpg-query 명령이 stdout에 아무것도 쓰지 않고 grep이 항상 리턴 코드를 던지기 때문에 grep을 삭제했습니다. 설치된 경우 dpkg-query 리턴 코드는 0입니다.
tahoar

2
1. 게시물에 "Debian"을 태그하지 마십시오. 2. 나는 당신 grep이 명령에 사용 된 부분을 ​​이해하지 못했다고 생각합니다 . 그래서 당신은 그것을 제거했고, 이제 작동하지 않는다고 말합니까? 일치 하지 않는 경우 , 즉 프로그램이 설치 되지 않았 거나 사용할 수없는 경우 또는 프로그램이 설치된 경우 grep -q리턴 코드를 제공합니다 . 나는 내 게시물에서 그것을 설명했다. 10
Daniel Andersson

1
#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps

-1, 질문은 종속성 검사에 관한 것이 아닙니다. 또한, 명령의 일부가 무엇을하고 있는지 설명하십시오. 그렇지 않으면 다른 사람들이 무슨 일이 일어나고 있는지 볼 수 없습니다.
Daniel Andersson

DEPS=$(echo {dialog,sqlite3,openssh-client})로 동일하게 작성할 수 있습니다 DEPS="dialog sqlite3 openssh-client".
Daniel Andersson

1

나는 Daniel Andersson의 대답이 마음에 들지만 효과가 없었습니다. 우분투 12.04에 있습니다.

로부터 dpkg를 man 페이지 , db:Status-abbrev단지 1.16.2+ dpkg를 작동합니다

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

내 솔루션은 레거시 동작을 사용하고 Status포맷터 만 사용하는 것이 었습니다 .

dpkg-query -Wf'${Status}' {my_pkg_name}

출력

install ok installed 

나는 이것이 다른 표현에서 "ii"에 대한 영감이라고 생각합니다.

따라서 Daniel Andersson의 답변을 이전 버전의 dpkg 및 이전 Ubuntu 배포판에서 작동하도록 완전히 조정하려면 다음을 수행하십시오.

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

보고:

  • 0-패키지가 설치되었거나
  • 1-패키지가 설치되지 않았습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.