ทดสอบว่ามีการติดตั้งแพ็คเกจใน APT หรือไม่


10

ฉันต้องการวิธีเชลล์สคริปต์เพื่อทดสอบ / รายงานหากมีการติดตั้งแพ็คเกจ ฉันไม่ต้องการรายละเอียดเพียงกลับบูลีนเพื่อตั้งค่าการไหลของตรรกะ ฉันดูที่Find หากมีการติดตั้งแพ็กเกจแต่dpkgส่งคืนเอาต์พุตที่ซับซ้อนและการเปลี่ยนแปลงรูปแบบขึ้นอยู่กับว่าแพคเกจนั้นอยู่ในที่เก็บ Debian หรือใน Ubuntu 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ในเชลล์สคริปต์) หากมีการติดตั้งแพ็กเกจเป็นเท็จ (สถานะออก1) เป็นอย่างอื่น

  • -Wหมายถึง "แสดง" ( dpkg-queryต้องมีการกระทำที่ร้องขอ)
  • -f เปลี่ยนรูปแบบของเอาต์พุต
  • db:Status-abbrev เป็นรูปแบบย่อของสถานะแพ็กเกจ
  • 2>/dev/nullปิดเสียงdpkg-queryหากกำหนดชื่อแพ็คเกจที่ไม่ถูกต้อง วิธีจัดการสิ่งนี้ควรเป็นปัญหาเป็นกรณี ๆ ไป
  • grep -q ผลตอบแทนจริงถ้ามีการแข่งขันเป็นเท็จเป็นอย่างอื่น

หากมีการใช้บ่อยมันอาจจะทำให้ฟังก์ชั่นที่เรียบง่าย:

#!/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

@ Daniel ฉันชอบวิธีส่งคืนรหัส โปรดดูคำตอบของฉันพร้อมรายละเอียดในรหัส
tahoar

ใน 10.04 ตัวเลือกการจัดรูปแบบ db: Status-abbrev ไม่มีอยู่จริง - ฉันใช้แล้ว: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'มีผลเหมือนกัน
scottynomad

1

ฉันทดสอบคำแนะนำของ Daniel เกี่ยวกับแพ็คเกจสามชุดด้วยผลลัพธ์เหล่านี้:

  1. ไม่ได้ติดตั้งแพ็คเกจที่เก็บ Native Debian:

    ~$ 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ส่วนหนึ่งในการวาง ฉันไม่สามารถทำซ้ำปัญหาของคุณได้จริง แต่อาจเป็นเพราะตัวอย่างรหัสไม่สมบูรณ์ดังนั้นโปรดแก้ไข คุณใช้ Debian หรือ Ubuntu หรือไม่
Daniel Andersson

ฉันใช้ Ubuntu 10.04 (PPA นั้นรองรับเดเบียนโดยตรงหรือไม่) รหัสของฉันทำ grep ของคุณตกเพราะ 1) คำสั่ง dkpg-query เขียนอะไรไปยัง stdout และ grep จะส่งรหัสส่งคืนเสมอ dpkg-query returncode เป็น 0 หากติดตั้งแล้ว
tahoar

2
1. อย่าแท็กโพสต์ "Debian" ของคุณ 2. ฉันไม่คิดว่าคุณเข้าใจส่วนที่grepเล่นในคำสั่งคุณจึงถอดมันออกและตอนนี้คุณบอกว่ามันใช้งานไม่ได้? grep -qให้โค้ดส่งคืน1หากไม่ตรงกันเช่นโปรแกรมไม่ได้ติดตั้งหรือไม่พร้อมใช้งานหรือ0หากติดตั้งโปรแกรม ฉันอธิบายว่าในโพสต์ของฉัน
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 แต่มันไม่ได้ผลสำหรับฉัน ฉันใช้ Ubuntu 12.04

จากหน้าคน dpkg , db:Status-abbrevจะทำงานเฉพาะใน dpkg 1.16.2+:

          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 distros เก่า:

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.