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


20

ฉันมีข้อกำหนดที่ง่าย ฉันต้องการกำหนดตัวแปรหลายตัวที่จะสอดคล้องกับจำนวนแพ็คเกจที่ฉันต้องการติดตั้งผ่านเชลล์สคริปต์

โค้ดตัวอย่างด้านล่าง:

MISC="shutter pidgin"
WEB="apache2 mongodb"

for pkg in $MISC $WEB; do
    if [ "dpkg-query -W $pkg | awk {'print $1'} = """ ]; then
        echo -e "$pkg is already installed"
    else
        apt-get -qq install $pkg
        echo "Successfully installed $pkg"
    fi
done

ทุกอย่างทำงานได้ดี แต่ตรรกะดูเหมือนว่ามีข้อบกพร่องเพราะไม่ได้ติดตั้งแพ็คเกจที่ฉันต้องการอย่างน่าเชื่อถือ อาจกล่าวได้ว่าติดตั้งไว้แล้วหรือกำลังพยายามติดตั้งแพคเกจที่ติดตั้งไว้ก่อนหน้านี้แล้ว

ฉันได้ลองด้วยcommand -vหรือต่อไปนี้:

if [ "dpkg -l | awk {'print $2'} | grep --regexp=^$pkg$ != """ ]; then

และถึงแม้จะมี-nและ-zธงเพื่อตรวจสอบว่าสตริงกลับมาว่างเปล่า ค่อนข้างแน่ใจว่าฉันขาดความรู้สึกที่ดีที่นี่

คุณมีความคิดว่าฉันจะทำอย่างไรเพื่อให้แน่ใจว่ามีการติดตั้งแพ็คเกจจริงหรือไม่?

ขอบคุณ!


สิ่งที่เป็นอันตรายหากคุณเรียกapt-get installใช้แพ็คเกจที่ติดตั้งด้วย apt-get install $MISC $WEBคุณก็สามารถโทร
jarno

คำตอบ:


15

เป็นหลักคุณจะต้องเปลี่ยนifเงื่อนไขด้วย

if dpkg --get-selections | grep -q "^$pkg[[:space:]]*install$" >/dev/null; then

มันเป็นไปไม่ได้ที่จะใช้dpkg-queryเพราะมันจะคืนค่าจริงเช่นกันสำหรับแพ็กเกจที่ลบออก แต่ไม่ถูกลบทิ้ง

นอกจากนี้ฉันขอแนะนำให้ตรวจสอบรหัสออกapt-getก่อนที่จะให้ข้อความที่ประสบความสำเร็จ

if apt-get -qq install $pkg; then
    echo "Successfully installed $pkg"
else
    echo "Error installing $pkg"
fi

อะไร&>ทำอย่างไร
Taymon

@Taymon: เปลี่ยนเส้นทางทั้ง stdin และ stderr ไปยังไฟล์ที่กำหนด ( /dev/nullในกรณีนี้) เพราะเราไม่ต้องการเอาต์พุตเพียงแค่รหัสทางออก มันจะทำงานเฉพาะในbash(บรรทัดแรกของสคริปต์จะต้องมี#!/bin/bash) >/dev/null 2>&1การใช้งานอย่างอื่น
enzotib

@Taymon: ฉันเปลี่ยนตรรกะเพราะฉันพบข้อบกพร่องในการแก้ปัญหาก่อนหน้านี้
enzotib

ระวัง: หากใช้ bash และตั้งค่าตัวเลือก pipefail แล้ว grep -q สามารถสร้าง Heisenbugs โดยพื้นฐานแล้ว grep จะออกก่อนที่ dpkg จะเขียนเสร็จ (คุณต้องการสถานะ 0 exit ในกรณีนั้น) ดังนั้น dpkg จึงไม่สามารถเขียนไปที่ไพพ์ (ซึ่งจะสร้างสถานะทางออกที่ไม่ใช่ 0) ให้แน่ใจว่าไม่ได้ตั้งค่า pipefail หรือละทิ้งประสิทธิภาพที่เพิ่มขึ้น (อาจจะเล็ก) จากตัวเลือก "-q"
Ron Burk

2

คุณสามารถทดสอบโดย dpkg-query:

if dpkg-query -W -f'${Status}' "$pkg" 2>/dev/null | grep -q "ok installed"; then

โปรดทราบว่า * และ? เป็นสัญลักษณ์แทนหากปรากฏเป็น $ pkg ฉันเดาว่า dpkg-query อาจพิมพ์ "ติดตั้งที่จำเป็นต้องเริ่มต้นใหม่" แทนที่จะเป็น "ติดตั้ง ok" หากแพ็กเกจขาดและจำเป็นต้องติดตั้งใหม่โดยคำสั่งapt-get install --reinstallซึ่งสามารถใช้ในการติดตั้งแพ็คเกจใหม่ได้เช่นกัน


0
#to check package is installed or not without distribution dependency
#!/bin/bash
read -p "Package Name: " pkg
which $pkg > /dev/null 2>&1
if [ $? == 0 ]
then
echo "$pkg is already installed. "
else
read -p "$pkg is not installed. Answer yes/no if want installation_ " request
if  [ $request == "yes" ]
then
yum install $pkg
fi
fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.