ตรวจสอบว่ามีการติดตั้งแพกเกจ apt-get หรือไม่จากนั้นติดตั้งหากไม่ได้อยู่ใน Linux


223

ฉันกำลังทำงานกับระบบ Ubuntu และในปัจจุบันนี่คือสิ่งที่ฉันทำ:

if ! which command > /dev/null; then
   echo -e "Command not found! Install? (y/n) \c"
   read
   if "$REPLY" = "y"; then
      sudo apt-get install command
   fi
fi

นี่คือสิ่งที่คนส่วนใหญ่จะทำ? หรือมีวิธีการแก้ปัญหาที่สง่างามมากขึ้น?


7
ชื่อคำสั่งไม่ได้สะท้อนถึงชื่อแพ็คเกจที่เคยเป็น เป้าหมายที่ใหญ่กว่าของคุณคืออะไร ทำไมคุณไม่ลองติดตั้งเลยและในกรณีที่แย่ที่สุดก็ไม่ได้เนื่องจากติดตั้งไว้แล้ว
viam0Zah

8
โชคดีที่การติดตั้ง apt-get นั้นเป็น idempotent ดังนั้นจึงปลอดภัยที่จะเรียกใช้และไม่ต้องกังวลว่าจะติดตั้งหรือไม่
David Baucum

@ ข้อคิดเห็นของ DavidBaucum ควรเป็นคำตอบที่จะได้รับคะแนนเสียงมากที่สุด
Nirmal

@ ใกล้เคียงตอบแล้ว
David Baucum

1
ที่เกี่ยวข้องคุณควรใช้command -v <command>; which <command>ไม่ ดูที่ตรวจสอบว่ามีโปรแกรมอยู่จากสคริปต์ Bashหรือไม่
jww

คำตอบ:


314

หากต้องการตรวจสอบว่าpackagenameติดตั้งแล้วหรือไม่ให้พิมพ์:

dpkg -s <packagename>

นอกจากนี้คุณยังสามารถใช้dpkg-queryที่มีเอาท์พุท neater สำหรับวัตถุประสงค์ของคุณและรับบัตรเสริมด้วย

dpkg-query -l <packagename>

หากต้องการค้นหาแพ็คเกจที่เป็นเจ้าของcommandลอง:

dpkg -S `which <command>`

สำหรับรายละเอียดเพิ่มเติมโปรดดูบทความค้นหาว่ามีการติดตั้งแพคเกจใน Linuxและแผ่นชีท dpkgหรือไม่


32
ถ้าคุณเป็นคนที่ต้องการสิ่งนี้โดยทางโปรแกรมคุณสามารถใช้ข้อมูลนี้ได้ อย่างไรก็ตามคุณไม่สามารถพึ่งพารหัสส่งคืนได้ที่นี่เพื่อสร้างสคริปต์หรือเอาต์พุต / ขาดเอาต์พุตเพียงอย่างเดียวสำหรับการสร้างสคริปต์ คุณจะต้องสแกนเอาต์พุตของคำสั่งเหล่านี้เพื่อ จำกัด ประโยชน์สำหรับคำถามนี้
UpAndAdam

4
ผิดปกติพอฉันเพิ่งค้นพบว่า dpkg-query ใช้เพื่อส่งคืน 1 บนแพคเกจที่ขาดหายไปตอนนี้ (Ubuntu 12.04) ส่งกลับ 0 ทำให้ทุกปัญหาในเจนกินส์ของฉันสร้างสคริปต์การตั้งค่าโหนด! dpkg -s ส่งคืน 0 บนแพ็กเกจที่ติดตั้งและ 1 บนแพ็กเกจไม่ได้ติดตั้ง
Therealstubot

18
เฮ้ OP ขอifการใช้งาน ฉันกำลังมองหาifการใช้งาน
Tomáš Zato - Reinstate Monica

1
@Therealstubot: ฉันยังใช้ Ubuntu 12.04 และdpkg -sส่งคืน 1 บนแพ็คเกจที่หายไปและ 0 เป็นอย่างอื่นตามที่ควรจะเป็น รุ่นก่อนหน้า (หรือล่าสุด) แตกต่างกันอย่างไร
MestreLion

4
หมายเหตุ: dpkg -sส่งคืนศูนย์ถ้ามีการติดตั้งแพคเกจแล้วนำออก - ในกรณีนี้มันจะStatus: deinstall ok config-filesคล้ายกันดังนั้นจึงเป็น "ok" - สำหรับฉันแล้วนี่ไม่ใช่การทดสอบที่ปลอดภัย dpkg-query -lดูเหมือนจะไม่ส่งคืนผลลัพธ์ที่เป็นประโยชน์ในกรณีนี้เช่นกัน
คม

86

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

REQUIRED_PKG="some-package"
PKG_OK=$(dpkg-query -W --showformat='${Status}\n' $REQUIRED_PKG|grep "install ok installed")
echo Checking for $REQUIRED_PKG: $PKG_OK
if [ "" = "$PKG_OK" ]; then
  echo "No $REQUIRED_PKG. Setting up $REQUIRED_PKG."
  sudo apt-get --yes install $REQUIRED_PKG 
fi

หากสคริปต์ทำงานภายใน GUI (เช่นเป็นสคริปต์ Nautilus) คุณอาจต้องการแทนที่การเรียกใช้ 'sudo' ด้วย 'gksudo'


5
--force-yesดูเหมือนว่าเป็นความคิดที่ไม่ดี จาก man page: "นี่เป็นตัวเลือกที่อันตรายที่จะทำให้ apt-get เพื่อดำเนินการต่อโดยไม่ต้องแจ้งถ้ามันทำอะไรที่อาจเป็นอันตรายไม่ควรใช้ยกเว้นในสถานการณ์พิเศษการใช้ --force-yes อาจทำลายระบบของคุณได้ !" การใช้สคริปต์ทำให้ยิ่งแย่ลงไปอีก
กิจกรรมที่ลดลง

68

สายการบินเดียวคืนค่า 1 (ติดตั้ง) หรือ 0 (ไม่ได้ติดตั้ง) สำหรับแพ็คเกจ 'นาโน'

$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")

แม้ว่าแพคเกจจะไม่มีอยู่ / ไม่สามารถใช้ได้

ตัวอย่างด้านล่างจะติดตั้งแพ็คเกจ 'นาโน' หากไม่ได้ติดตั้ง ..

if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
  apt-get install nano;
fi

4
การเปลี่ยนแปลงของฉันเกี่ยวกับเรื่องนี้:dpkg-query -W -f='${Status}' MYPACKAGE | grep -q -P '^install ok installed$'; echo $?
ThorSummoner

@ThorSummoner: สนใจที่จะอธิบายว่าทำไมคุณถึงดีกว่า?
knocte

1
@ Knocte ฉันไม่แน่ใจว่ามีการโต้เถียงที่จะทำให้ดีขึ้นอย่างเป็นกลาง แม้ว่าฉันจะมั่นใจว่าโพสต์แบบต่อบรรทัดของ verbatim จะดำเนินการผลลัพธ์ผลลัพธ์ซึ่งฉันไม่ต้องการทิ้งคำตอบไว้ ซับหนึ่งที่ฉันแสดงเป็นตัวอย่างการรับ (การพิมพ์) เพียงแค่รหัสทางออก
ThorSummoner

1
@ThorSummoner คุณไม่จำเป็นต้องgrep -Pมี regex แบบง่ายๆ
tripleee

7
เรียบง่าย: if ! dpkg-query -W -f='${Status}' nano | grep "ok installed"; then apt install nano; fi- ไม่จำเป็นต้องใช้grep -cเพียงใช้สถานะทางออกของgrep
Stephen Ostermiller

17

dpkg -s การใช้งานแบบเป็นโปรแกรมพร้อมการติดตั้งอัตโนมัติ

ฉันชอบdpkg -sเนื่องจากออกจากสถานะ1หากไม่มีแพ็คเกจใดติดตั้งอยู่ทำให้ง่ายต่อการทำงานอัตโนมัติ:

pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
  sudo apt-get install $pkgs
fi

man dpkg ไม่ได้บันทึกสถานะการออก แต่น่าเสียดายที่ฉันเชื่อว่าควรเชื่อถือได้:

-s, --status package-name...
    Report status of specified package.

สิ่งหนึ่งที่ควรทราบคือการทำงาน:

sudo apt remove <package-name>

ไม่จำเป็นต้องลบไฟล์ทั้งหมดทันทีสำหรับบางแพ็คเกจ (แต่ทำเพื่อคนอื่นไม่แน่ใจว่าทำไม?) และเพียงทำเครื่องหมายแพ็คเกจเพื่อลบ

ในสถานะนี้แพคเกจดูเหมือนว่าจะยังคงใช้งานได้และเป็นไฟล์ของมันยังคงมีอยู่ แต่มันถูกทำเครื่องหมายเพื่อลบในภายหลัง

ตัวอย่างเช่นถ้าคุณเรียกใช้:

pkg=certbot

sudo apt install -y "$pkg"
dpkg -s "$pkg"
echo $?

sudo apt remove -y "$pkg"
dpkg -s "$pkg"
echo $?
ls -l /usr/lib/python3/dist-packages/certbot/reporter.py

sudo apt remove --purge certbot
dpkg -s "$pkg"
echo $?
ls -l /usr/lib/python3/dist-packages/certbot/reporter.py

แล้ว:

  • สองecho $?เอาต์พุตแรก0เท่านั้นที่สามเท่านั้นที่เอาต์พุต1

  • ผลลัพธ์สำหรับครั้งแรกdpkg -s certbotประกอบด้วย:

    Status: deinstall ok installed

    ในขณะที่สองพูดว่า:

    Status: deinstall ok config-files

    และจะหายไปหลังจากการล้าง:

    dpkg-query: package 'certbot' is not installed and no information is available
  • ไฟล์/etc/logrotate.d/certbotยังคงปรากฏอยู่ในระบบหลังจากapt removeแต่ไม่ใช่หลังจาก--purgeนั้น

    แต่ไฟล์ยังคงอยู่แม้หลังจากที่/usr/lib/python3/dist-packages/certbot/reporter.py--purge

ฉันไม่เข้าใจว่าทำไม แต่ด้วยhelloแพคเกจที่สองdpkgหลังจากapt removeแสดงให้เห็นว่าเขาได้ถูกลบแพคเกจโดยไม่ต้อง--purge:

dpkg-query: package 'hello' is not installed and no information is available

เอกสารยังไม่ชัดเจนมากเช่น:

sudo apt dselect-upgrade

ไม่ได้ลบออกcertbotเมื่อมีการทำเครื่องหมายว่าdeinstallแม้ว่าman apt-getดูเหมือนว่าจะระบุว่า:

dselect-upgradeใช้ร่วมกับแพ็คเกจบรรจุภัณฑ์ Debian แบบดั้งเดิมคือ dselect (1) dselect-upgrade ตามการเปลี่ยนแปลงที่ทำโดย dselect (1) ไปยังฟิลด์สถานะของแพ็คเกจที่มีอยู่และดำเนินการที่จำเป็นเพื่อให้ทราบสถานะนั้น (เช่นการลบเก่าและการติดตั้งแพ็คเกจใหม่)

ดูสิ่งนี้ด้วย:

ทดสอบกับ Ubuntu 19.10

aptแพ็คเกจPython

มีแพ็คเกจ Python 3 ที่ติดตั้งไว้แล้วซึ่งเรียกว่าaptใน Ubuntu 18.04 ซึ่งแสดงถึงอินเทอร์เฟซ Python apt!

สคริปต์ที่ตรวจสอบว่ามีการติดตั้งแพคเกจและติดตั้งหรือไม่หากไม่สามารถดูได้ที่: วิธีการติดตั้งแพคเกจโดยใช้ python-apt API

นี่คือสำเนาสำหรับการอ้างอิง:

#!/usr/bin/env python
# aptinstall.py

import apt
import sys

pkg_name = "libjs-yui-doc"

cache = apt.cache.Cache()
cache.update()
cache.open()

pkg = cache[pkg_name]
if pkg.is_installed:
    print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
    pkg.mark_install()

    try:
        cache.commit()
    except Exception, arg:
        print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))

ตรวจสอบว่าปฏิบัติการอยู่ในPATHแทน

ดู: ฉันจะตรวจสอบได้อย่างไรว่าโปรแกรมนั้นมีอยู่จากสคริปต์ Bash หรือไม่


Ciro, ou ไม่สามารถพึ่งพารหัสทางออก "dpkg -s" ตัวอย่างเช่นหากคุณ "apt ติดตั้ง" แพคเกจแล้ว "apt ลบ" มันและพยายามที่จะ "dpkg -s packagename" แล้วคุณจะสังเกตเห็นสถานะ: deinstall และออกจากรหัสศูนย์ (เช่นถ้าติดตั้ง) คุณต้องแยกวิเคราะห์เอาต์พุต "dpkg -s"
Dmitry Shevkoplyas

@DmitryShevkoplyas ขอบคุณสำหรับการรายงาน ฉันไม่สามารถทำซ้ำบน Ubuntu 19.10 sudo apt install hello; dpkg -s hello; echo $?; sudo apt remove hello; dpkg -s hello; echo $?ด้วย: คุณสามารถให้รายละเอียดเพิ่มเติมได้หรือไม่?
Ciro Santilli 郝海东冠状病六四事件法轮功

1
แน่นอน - สำหรับกรณีทดสอบของคุณด้วย "hello" package "dpkg -s" อย่างถูกต้องแสดงให้เห็นถึงแพคเกจที่ไม่ได้ติดตั้งและให้รหัสออกที่คาดไว้ "1" แต่ลองใช้ instal / remove check เดียวกันกับแพคเกจ "certbot" จากนั้นคุณจะเห็น "สถานะ: deinstall ok config-files" เป็นเอาต์พุต "dpkg -s" หลังจาก "apt remove certbot" ของคุณและรหัสทางออกไม่ถูกต้องแสดงให้เราเห็น "0" สมมติฐานที่ผิดของฉันคือมันเป็นกรณีที่แน่นอนสำหรับแพคเกจอื่น ๆ แต่ดูเหมือนว่ามันจะไม่เหมือนกันสำหรับทุกคนซึ่งยิ่งแย่ลงและคาดการณ์ได้น้อยลง แยกวิเคราะห์ "dpkg -s" คุณต้อง (c) Yoda :)
Dmitry Shevkoplyas

11

ฉันเสนอการอัปเดตนี้เนื่องจาก Ubuntu เพิ่ม "Personal Package Archive" (PPA) เช่นเดียวกับที่ตอบคำถามนี้และแพคเกจ PPA มีผลลัพธ์ที่ต่างออกไป

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

    ~$ dpkg-query -l apache-perl
    ~$ echo $?
    1
  2. แพคเกจ PPA ลงทะเบียนในโฮสต์และติดตั้ง:

    ~$ dpkg-query -l libreoffice
    ~$ echo $?
    0
  3. PPA แพ็คเกจที่ลงทะเบียนไว้บนโฮสต์ แต่ไม่ได้ติดตั้ง:

    ~$ dpkg-query -l 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.

โพสต์เมื่อ: /superuser/427318/test-if-a-package-is-installed-in-apt/427898


2
หากคุณติดตั้งและลบแพ็คเกจถัดไปคุณจะใช้แพ็คเกจ dpkg-query echo $ จะเป็น 0 เช่นกันหากไม่ได้ติดตั้งแพ็คเกจ
Pol Hallen

8

UpAndAdam wrote:

อย่างไรก็ตามคุณไม่สามารถพึ่งพารหัสส่งคืนได้ที่นี่เพื่อสร้างสคริปต์

จากประสบการณ์ของฉันคุณสามารถพึ่งพารหัสทางออกของ dkpg

โค้ดส่งคืนของdpkg -sคือ0หากแพ็กเกจถูกติดตั้งและ1ถ้าไม่ใช่ดังนั้นโซลูชันที่ง่ายที่สุดที่ฉันพบคือ:

dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name>

ทำงานได้ดีสำหรับฉัน ...


11
หลังจากapt-get remove <package>, dpkg -s <package>ยังคงกลับ 0 แม้ว่าแพคเกจเป็นdeinstalled
ThorSummoner

7

ดูเหมือนว่าจะทำงานได้ดีทีเดียว

$ sudo dpkg-query -l | grep <some_package_name> | wc -l
  • มันจะส่งกลับ0ถ้าไม่ได้ติดตั้งหรือบางหมายเลข> 0ถ้าติดตั้ง

8
grep | wc -lเป็น antipattern grep -qเพื่อตรวจสอบว่าสิ่งที่มีอยู่แล้วคุณต้องการเพียงแค่ ที่จริงนับเกิดขึ้น (ซึ่งจะเป็นประโยชน์น้อยมากในการเรียงลำดับของสถานการณ์นี้) grep -cการใช้งาน
tripleee

@tripleee งั้นdpkg -s zip | grep -c "Package: zip"เหรอ? (ใช้ zip เป็นแพ็คเกจตัวอย่าง)
David Tabernero M.

@Davdriver นั่นไม่ใช่สิ่งที่กล่าวมาข้างต้น แต่ใช่ ในสคริปต์คุณอาจต้องการgrep -q 'Package: zip'ส่งคืนรหัสออกซึ่งระบุว่าพบผลลัพธ์โดยไม่พิมพ์อะไรหรือไม่
tripleee

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

4

ฉันตัดสินตามคำตอบของ Nultyi :

MISSING=$(dpkg --get-selections $PACKAGES 2>&1 | grep -v 'install$' | awk '{ print $6 }')
# Optional check here to skip bothering with apt-get if $MISSING is empty
sudo apt-get install $MISSING

โดยทั่วไปข้อความแสดงข้อผิดพลาดจากdpkg --get-selectionsนั้นจะง่ายกว่าในการแยกวิเคราะห์ส่วนใหญ่อื่น ๆ เพราะมันไม่ได้รวมสถานะเช่น "deinstall" นอกจากนี้ยังสามารถตรวจสอบหลายแพ็คเกจพร้อมกันสิ่งที่คุณไม่สามารถทำได้ด้วยรหัสข้อผิดพลาด

คำอธิบาย / ตัวอย่างเช่น:

$ dpkg --get-selections  python3-venv python3-dev screen build-essential jq
dpkg: no packages found matching python3-venv
dpkg: no packages found matching python3-dev
screen                                          install
build-essential                                 install
dpkg: no packages found matching jq

ดังนั้น grep จะลบแพ็กเกจที่ติดตั้งออกจากรายการและ awk จะดึงชื่อแพ็กเกจออกจากข้อความแสดงข้อผิดพลาดซึ่งทำให้MISSING='python3-venv python3-dev jq'สามารถแทรกเข้าไปในคำสั่งการติดตั้งได้เล็กน้อย

ฉันไม่ได้ประกาศอย่างไม่เห็นด้วยapt-get install $PACKAGESเพราะดังที่ได้กล่าวไว้ในความคิดเห็นนี้สามารถอัปเกรดแพ็คเกจที่คุณคาดไม่ถึงโดยที่คุณไม่ได้วางแผน ไม่ใช่ความคิดที่ดีสำหรับกระบวนการอัตโนมัติที่คาดว่าจะมีเสถียรภาพ


ฉันชอบวิธีนี้ กระชับและทดสอบหลายแพ็คเกจพร้อมกัน นอกจากนี้คุณสามารถทำการตรวจสอบเพิ่มเติมได้อย่างง่ายดาย[[ ! -z $MISSING ]] && sudo apt-get install $MISSING
Shenk

3

ฉันได้พบวิธีแก้ไขทั้งหมดข้างต้นสามารถสร้างผลบวกปลอมหากมีการติดตั้งแพคเกจแล้วลบออกแพคเกจการติดตั้งยังคงอยู่ในระบบ

ในการทำซ้ำ: ติดตั้งแพ็คเกจapt-get install curl
ลบแพ็คเกจapt-get remove curl

ตอนนี้ทดสอบคำตอบข้างต้น

คำสั่งต่อไปนี้ดูเหมือนว่าจะแก้ไขเงื่อนไขนี้:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'

สิ่งนี้จะส่งผลให้มีการติดตั้งที่ชัดเจน หรือไม่ได้ติดตั้ง


ไม่ใช่ทั้งหมดน่าเศร้า - ผลลัพธ์ที่เป็นไปได้อื่น ๆ ในกรณีนี้คือconfig-files- ดังนั้นฉันคิดว่า| grep -q "installed"จำเป็นต้องมีขั้นสุดท้ายเพื่อรับสถานะรหัสการทำงานที่เป็นประโยชน์
คม

ทำเช่นนั้น| grep -q '^installed$'
กระตือรือร้น

3

ดูเหมือนว่าในปัจจุบันapt-getมีตัวเลือก--no-upgradeที่ทำในสิ่งที่ OP ต้องการ:

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

Manpage จากhttps://linux.die.net/man/8/apt-get

ดังนั้นคุณสามารถใช้

apt-get install --no-upgrade package

และpackageจะถูกติดตั้งเฉพาะในกรณีที่ไม่ใช่



2

นี้จะทำมัน apt-get installคือ idempotent

sudo apt-get install command

5
มีสถานการณ์ที่apt-get installไม่พึงประสงค์ในการทำแพ็กเกจที่ติดตั้งแพ็กเกจไว้แล้วแม้ว่าคำสั่งนั้นจะเป็น idempotent ก็ตาม ในกรณีของฉันฉันกำลังติดตั้งแพ็กเกจบนระบบรีโมตด้วยโมดูล raw ของ Ansible ซึ่งจะรายงานระบบว่ามีการเปลี่ยนแปลงทุกครั้งหากฉันรันapt-get installโดยไม่เลือกปฏิบัติ เงื่อนไขแก้ปัญหานั้น
JBentley

1
@Bentley นั่นเป็นจุดที่ดี แพคเกจที่ติดตั้งในฐานะเป็นส่วนหนึ่งของการพึ่งพาจะได้รับการทำเครื่องหมายว่าติดตั้งด้วยตนเองแล้วจะไม่ถูกลบออกเมื่อการอ้างอิงนั้นถูกลบหากคุณได้รับการติดตั้ง
David Baucum

2

ใช้:

apt-cache policy <package_name>

หากยังไม่ได้ติดตั้งจะแสดง:

Installed: none

มิฉะนั้นจะแสดง:

Installed: version

1

คุณลักษณะนี้มีอยู่ใน Ubuntu และ Debian แล้วในcommand-not-foundแพ็คเกจ


15
matt @ matt-ubuntu: ~ $ คำสั่งไม่พบคำสั่งไม่พบ: ไม่พบคำสั่ง ... lol
Matt Fletcher

1
command-not-foundเป็นผู้ช่วยเหลือแบบโต้ตอบไม่ใช่เครื่องมือที่จะทำให้แน่ใจว่าคุณมีการอ้างอิงที่คุณต้องการ แน่นอนวิธีที่เหมาะสมในการประกาศการขึ้นต่อกันคือการทำแพคเกจซอฟต์แวร์ของคุณในแพ็คเกจ Debian และกรอกข้อมูลในไฟล์Depends:ของแพ็คเกจdebian/controlอย่างถูกต้อง
tripleee

1
apt list [packagename]

น่าจะเป็นวิธีที่ง่ายที่สุดในการทำนอกเหนือจากเครื่องมือ dpkg และ apt- * ที่เก่ากว่า


มันเป็นการดีสำหรับการตรวจสอบด้วยตนเอง แต่มันออกคำเตือนบอกว่า apt ไม่ได้มีไว้สำหรับการเขียนสคริปต์ - ตรงกันข้ามกับเครื่องมือ apt- *
Hontvári Levente


1

ฉันมีข้อกำหนดที่คล้ายกันเมื่อเรียกใช้การทดสอบในเครื่องแทนการเทียบท่า โดยทั่วไปฉันแค่ต้องการติดตั้งไฟล์ใด ๆ . deb พบว่าพวกเขาไม่ได้ติดตั้ง

# If there are .deb files in the folder, then install them
if [ `ls -1 *.deb 2> /dev/null | wc -l` -gt 0 ]; then
  for file in *.deb; do
    # Only install if not already installed (non-zero exit code)
    dpkg -I ${file} | grep Package: | sed -r 's/ Package:\s+(.*)/\1/g' | xargs dpkg -s
    if [ $? != 0 ]; then
        dpkg -i ${file}
    fi;
  done;
else
  err "No .deb files found in '$PWD'"
fi

ฉันเดาว่าพวกเขามีปัญหาเพียงอย่างเดียวที่ฉันเห็นคือมันไม่ได้ตรวจสอบหมายเลขเวอร์ชันของแพ็กเกจดังนั้นหากไฟล์. deb เป็นเวอร์ชันที่ใหม่กว่านี้จะไม่เขียนทับแพ็คเกจที่ติดตั้งในปัจจุบัน


1

สำหรับ Ubuntu apt มีวิธีที่เหมาะสมในการทำเช่นนี้ ด้านล่างนี้เป็นตัวอย่างสำหรับ google chrome:

apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable

ฉันเปลี่ยนเส้นทางข้อผิดพลาดเป็น null เพราะ apt เตือนไม่ให้ใช้ "cli ที่ไม่เสถียร" ฉันสงสัยว่ารายชื่อแพ็คเกจนั้นเสถียรดังนั้นฉันคิดว่ามันโอเคที่จะทิ้งคำเตือนนี้ไป -qq ทำให้ฉลาดสุดเงียบ


1
สิ่งนี้จะทำงานไม่ถูกต้องหากมีสิ่งใด "อัปเกรดได้"
Pawel Barcik

@ PawelBarcik จุดที่ดี ฉันได้อัปเดตคำตอบเพื่อรับมือกับสถานการณ์นั้นแล้ว
carlin.scott

0

คำสั่งนี้น่าจดจำที่สุด:

dpkg --get-selections <package-name>

หากติดตั้งแล้วจะพิมพ์:

<package-name> ติดตั้ง

มิฉะนั้นจะพิมพ์

ไม่พบแพ็คเกจที่ตรงกับ <package-name>

สิ่งนี้ถูกทดสอบบน Ubuntu 12.04.1 (แม่นยำ Pangolin)


4
dpkg --get-selections <package-name>ไม่ได้ตั้งรหัสออกเป็นไม่เป็นศูนย์เมื่อไม่พบแพ็คเกจ
Lucas

0

มีหลายสิ่งที่บอก แต่สำหรับฉันวิธีที่ง่ายที่สุดคือ:

dpkg -l | grep packagename

0

ใน Bash:

PKG="emacs"
dpkg-query -l $PKG > /dev/null || sudo apt install $PKG

โปรดทราบว่าคุณสามารถมีสตริงที่มีหลายแพ็คเกจใน PKG


0

ฉันใช้วิธีต่อไปนี้:

which mySQL 2>&1|tee 1> /dev/null
  if [[ "$?" == 0 ]]; then
                echo -e "\e[42m MySQL already installed. Moving on...\e[0m"
        else
        sudo apt-get install -y mysql-server
                if [[ "$?" == 0 ]]; then
                        echo -e "\e[42mMy SQL installed\e[0m"
                else
                        echo -e "\e[42Installation failed\e[0m"
                fi
        fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.