Membuat daftar paket yang diinstal secara manual dan menanyakan paket individual

183

Saya ingin mendapatkan daftar paket yang diinstal secara manual oleh aptatau aptitudedan dapat mengetahui apakah suatu foobarpaket diinstal secara manual atau otomatis. Apakah ada cara yang rapi untuk melakukan itu dari baris perintah?

Umang
sumber
Lihat jawaban ini di unix.stackexchange.com untuk solusi yang menyaring paket saham.
Dirk Bergstrom
Kemungkinan duplikat? - askubuntu.com/questions/365
jrg
Solusi yang sangat bagus yang mengecualikan paket yang diinstal secara default: Daftar Ubuntu menginstal paket secara eksplisit
pcworld
Hati-hati dengan komentar jawaban di sini. Orang-orang tidak mengatakan cara lebih banyak paket muncul, tetapi mereka lupa bahwa ada paket dependensi yang diinstal dari manual yang diinstal.
Andre Figueiredo

Jawaban:

206

Anda dapat menggunakan salah satu dari dua baris satu ini. Keduanya menghasilkan output yang sama persis pada mesin saya dan lebih tepat daripada semua solusi yang diajukan sampai sekarang (6 Juli 2014) dalam pertanyaan ini.

Menggunakan apt-mark:

comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)

Menggunakan aptitude:

comm -23 <(aptitude search '~i !~M' -F '%p' | sed "s/ *$//" | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)

Sangat sedikit paket masih jatuh melalui celah-celah, walaupun aku curiga ini yang benar-benar dipasang oleh pengguna, baik tepat setelah instalasi melalui setup bahasa lokalisasi atau misalnya melalui installer Totem codec. Juga, versi linux-header juga tampaknya menumpuk, meskipun saya hanya menginstal metapackage non-spesifik. Contoh:

libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29    

Bagaimana cara kerjanya:

  1. Dapatkan daftar paket yang diinstal secara manual. Untuk aptitude, sedstrip tambahan mengeluarkan spasi kosong di akhir baris.
  2. Dapatkan daftar paket yang diinstal tepat setelah instalasi baru.
  3. Bandingkan file, hanya output baris dalam file 1 yang tidak ada dalam file 2.

Kemungkinan lain tidak berfungsi juga:

  • Menggunakan ubuntu-14.04-desktop-amd64.manifestfile (di sini untuk Ubuntu 14.04) bukan /var/log/installer/initial-status.gz. Lebih banyak paket ditampilkan sebagai diinstal secara manual meskipun tidak.
  • Menggunakan apt-mark showautobukan /var/log/installer/initial-status.gz. apt-markmisalnya tidak menyertakan paket xserver-xorg, sedangkan file lain tidak.

Saya menggunakan berbagai postingan StackExchange lainnya sebagai referensi, namun tidak ada yang bekerja sebaik solusi di atas:

Keduanya mendaftar lebih banyak paket daripada solusi di atas.

EDIT: Apa yang harus dilakukan jika Anda telah memutakhirkan dari rilis sebelumnya:

Jika Anda telah memutakhirkan Ubuntu dari satu rilis ke yang berikutnya, Anda mungkin perlu menyesuaikan proses ini. Dalam hal ini, saya akan memeriksa file manifes dari rilis yang lebih baru (lihat di atas) di samping file initial-status.gz dari rilis saat ini. Anda dapat dengan mudah melakukannya dengan hanya menambahkan perbandingan lain. Hanya menggunakan file manifes tidak akan berfungsi, karena sayangnya file manifes tidak mengandung semua yang dilakukan oleh file initial_status.gz (saya telah memeriksa).

jmiserez
sumber
7
Ini tidak berhasil untuk saya karena /var/log/installer/initial-status.gzhilang. Saya juga ingin tahu apakah ini tergantung pada tanda apts manualatau tidak?
Anwar
1
Sayangnya tidak ada manifes untuk versi server.
Antti Haapala
Saya menjalankan showmanualperintah (di bawah). Dan gunakan communtuk membandingkan dua daftar (diurutkan). The showmanualHasil memberi saya 1.840 lebih paket unik dari apt-mark showmanualtidak ditampilkan dengan metode ini. Tidak ada paket yang unik untuk keluaran dari commperintah ini . Saya pikir lebih menarik untuk mencatat bahwa untuk PC saya, 894 paket terdaftar di Kedua hasil. Tidak yakin mengapa ada perbedaan besar. Beberapa (banyak?) Paket tampaknya rilis spesifik. Lainnya seperti XOrg, komponen GTK, dan lib*hal - hal lainnya dapat berupa pembaruan. Bagaimanapun jawaban ini adalah awal yang sangat bagus.
akan
Saya baru saja membandingkan solusi Anda dengan apt-mark showmanual. Sangat menarik berapa banyak perbedaan yang terlihat. daftar Anda memiliki 238 paket sementara pertunjukan kembali 1717 paket. Dari 2179 paket yang diinstal, hanya ada 223 di kedua daftar, 15 hanya di milik Anda (contoh: nodejs, lightdm) dan 223 hanya di showmanual (contoh: xserver-xorg, ubuntu-desktop). Rasanya daftar Anda lebih bermanfaat, tetapi tanpa mengetahui dari mana perbedaan ini berasal, tidak mudah untuk memutuskan ... (tapi saya cukup yakin saya menginstal nginx dan lightdm secara manual ...) [maaf saya baru saja menulis sama;)]
Daniel Alder
64

Di versi yang lebih baru dari paket apt, ada juga perintah apt-mark

apt-mark showmanual
Daniel Alder
sumber
35
Ini menunjukkan paket jauh lebih banyak daripada yang saya instal secara manual.
Umang
1
@ Unmang Anda benar. Saya akan mengatakan ini tidak seperti ini ketika saya menulis jawaban ini. Tidak ada alasan pada sistem saya untuk mempertimbangkan linux-image-3.11.0-*-genericdll sebagai manual
Daniel Alder
1
@Umang mungkin ini akan membantu Anda askubuntu.com/questions/432743/… , tetapi jawabannya tidak diterima. Faktanya, banyak paket instalasi baru sudah ditandai sebagai manual. Namun masih ada beberapa hal aneh. Untuk tetap dengan contoh saya: linux-image-3.13.0-24-genericmanual tetapi saat linux-image-3.13.0-27-genericini otomatis. Tampaknya pembaruan paket referensi (dalam hal ini linux-image-generic, yang mengubah dependensi), tanda manual secara otomatis ditetapkan
Daniel Alder
5
@DanielAlder beberapa paket instalasi baru harus ditandai sebagai manual. Jika tidak ada paket yang ditandai sebagai manual, seluruh sistem dapat dihapus apt-get autoremove. Ini jelas bukan yang Anda inginkan.
Anton K
2
Jika "diinstal secara manual" berarti "diinstal oleh pengguna setelah instalasi OS awal", ini bukan jawaban yang benar.
Seamus
21

Untuk Ubuntu 16.04, periksa file log /var/log/apt/history.log.

Sebagai contoh:

zgrep 'Commandline: apt' /var/log/apt/history.log /var/log/apt/history.log.*.gz

Ini tidak sempurna, tetapi cukup baik untuk menjelaskan apa yang saya instal dengan tangan. Letakkan -B 1pada grep untuk melihat kapan itu dipasang.

Contoh output

Commandline: apt install postgresql-9.5-plv8
Commandline: aptdaemon role='role-install-file' sender=':1.85'
Commandline: apt install task
Commandline: apt autoremove
Commandline: apt install atom
Commandline: apt upgrade
Commandline: apt-get install asciinema
Commandline: apt install iperf3
Commandline: apt upgrade
Commandline: apt-get install chromium-browser
Commandline: apt install joe cpanminus build-essential postgresql libdbd-pg-perl libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl libio-socket-ssl-perl libnet-ssleay-perl libssl-dev
Commandline: aptdaemon role='role-commit-packages' sender=':1.2314'
Commandline: apt install git
Commandline: apt install sqlite
Commandline: apt install whois
Commandline: apt install libdbd-pg-perl
Commandline: apt install perl-doc
Commandline: apt upgrade

Tidak yakin apakah ini mengambil aptitudeatau tidak. Tampaknya tidak mengambil instalasi dari aplikasi desktop Software Ubuntu.

s1037989
sumber
1
Dari semua jawaban selama bertahun-tahun, ini adalah satu-satunya yang mendekati server 18.04.
Quentin Skousen
20

apt-mark showauto | grep -iE '^foobar$' akan menampilkan "foobar" jika paket diinstal secara otomatis, tidak ada yang sebaliknya.

aptitude search '!~M ~i'akan mencantumkan paket yang tidak diinstal secara otomatis. Sayang sekali kemampuannya tidak akan menjadi bagian dari pemasangan default di Ubuntu Desktop mulai dari 10.10.

Lil o
sumber
aptitude searchmenunjukkan SEMUA paket bukan hanya yang diinstal secara manual (saya berasumsi itulah yang diinginkan OP)
Oli
1
@Oli: lihat pola pencarian bakat; pola yang saya gunakan di sana harus melakukan persis apa yang diinginkan OP.
Li Lo
Saya menjalankannya . Ini menunjukkan seluruh paket yang tidak diinstal.
Oli
7
Ada yang tidak beres dengan ini, saya menggunakan aptitude search '!~M ~i'dan daftar 1043 paket. Tidak mungkin saya menginstal banyak paket secara manual.
ThatGraemeGuy
Ini pasti tidak berfungsi seperti yang diminta, mencetak paket yang sudah diinstal juga.
Irfy
9

Skrip berikut akan mencetak semua paket yang tidak disetel ke pemasangan otomatis dan karenanya dipasang secara manual:

#!/usr/bin/python

try:
    import apt_pkg
except ImportError:
    print "Error importing apt_pkg, is python-apt installed?"
    sys.exit(1)

apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
    pkgname = tagfile.section.get("Package")
    autoInst = tagfile.section.get("Auto-Installed")
    if not int(autoInst):
        auto.add(pkgname)
print "\n".join(sorted(auto))

ini didasarkan pada bagaimana apt-mark mencetak paket yang diinstal secara otomatis.

txwikinger
sumber
Kudos untuk Anda, tuan. Ini sebenarnya berfungsi, berbeda dengan jawaban yang diterima.
Irfy
tunjukkan hanya beberapa paket untuk saya --- pasti hilang banyak dari mereka.
Rmano
Sama di sini, pasti hilang paket yang diinstal secara manual, tepat setelah saya menginstalnya.
David Ljung Madison
Menggunakan sys.exit(1)tanpa import sysdapat menyebabkan kesalahan pada versi python yang lebih baru. Entah import sysatau gunakan exit(1).
Videonauth
7

Untuk mendapatkan daftar semua paket (tidak diinstal, diinstal oleh pengguna atau diinstal secara default, di semua PPA), aptgunakan metode berikut:

apt list [option]

Opsi yang mungkin berguna untuk ini adalah:

--installed untuk hanya menampilkan paket-paket yang diinstal pada sistem (dari sekitar 50.000+)

--manual-installeduntuk membuat daftar paket yang secara eksplisit diinstal oleh perintah, baik secara langsung, atau sebagai dependensi.

Atau, Anda bisa melakukan:

apt list --manual-installed | grep -F \[installed\] untuk mendapatkan daftar paket yang dihasilkan dari perintah pengguna dan dependensinya saja, dan untuk mendapatkan informasi tambahan tentang mereka seperti versi dan arsitektur yang didukung (x86, x86_64, amd64, semua, dll.)

Aalok
sumber
5

Seperti yang dikomentari beberapa orang, kecakapan memainkan pertunjukan apt-mark tampaknya agak buggy (dan saya melaporkannya sebagai bug 727799 ). Ketika saya menggunakannya, itu sebenarnya melaporkan banyak hal yang bahkan tidak masuk / var / lib / apt / extended_states (di mana ini seharusnya disimpan) dan apt-get tidak mencatat hal-hal seperti yang diinstal di / var / lib / apt / extended_states (hanya di / var / lib / dpkg / status). Skrip python oleh txwikinger di atas diambil langsung dari / var / lib / apt / extended_states tetapi jika Anda menggunakannya hari ini sintaks mungkin tidak berfungsi (saya baru saja mulai membuat kesalahan dengan Kubuntu 13.10). Sintaks yang diperbarui adalah:

#!/usr/bin/python
import sys

try:
    import apt_pkg
except ImportError:
    print "Error importing apt_pkg, is python-apt installed?"
    sys.exit(1)

apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
    pkgname = tagfile.section.get("Package")
    autoInst = tagfile.section.get("Auto-Installed")
    if not int(autoInst):
        auto.add(pkgname)
print "\n".join(sorted(auto))

Bagi saya ini adalah daftar yang sangat pendek dari 5 item yang tampaknya tidak akurat juga.

cluelesscoder
sumber
1
Menggunakan sys.exit(1)tanpa import sysdapat menyebabkan kesalahan pada versi python yang lebih baru. Entah import sysatau gunakan exit(1).
Videonauth
4

Saya ingin memberikan solusi GUI.

masukkan deskripsi gambar di sini

  1. Buka Synaptic Package Manager

  2. Pergi ke Status

  3. Klik Installed (manual)

Ini akan memberikan daftar paket yang diinstal secara manual dengan apt atau aptitude.

Sayangnya saya tidak dapat menemukan opsi apa pun Custom Filtersuntuk mengetahui apakah suatu foobarpaket diinstal secara manual atau otomatis.

Jika paket di bawah Installedtetapi tidak di bawah Installed (manual)maka itu Dipasang secara otomatis. Jika paket di bawah Installed (manual)maka itu diinstal secara manual.

sinar biru
sumber
2

Jika tidak ada yang memberi Anda jawaban yang bagus menggunakan perintah apr-something, Anda bisa melakukannya dengan cara yang sulit . Apt-get menyimpan informasinya di / var / lib / apt / extended_states. File apa pun yang diinstal secara otomatis akan ditambahkan ke file ini. Jika Anda menginstal paket yang sudah ada di file ini secara manual, paket akan tetap di file ini tetapi dengan Auto-instal: 0 di baris kedua. Itu tidak dihapus.

Catatan: Seperti yang diharapkan, jawaban yang lebih baik yang cenderung berfungsi jika perubahan penempatan file telah muncul. Saya menyimpan milik saya kalau-kalau info tentang lokasi file berguna.

Javier Rivera
sumber
1
Tidak. Saya melihat sekilas file itu untuk menemukan bahwa liferea ditandai sebagai terinstal otomatis. Saya melakukan apt-get install lifereadan itu tidak menginstal tetapi saya mendapat output yang sesuatu dengan efek "ditandai sebagai diinstal secara manual". Sekarang liferea masih ada dalam file, kecuali baris berikutnya memiliki 0alih - alih a 1. Juga, Anda harus mengubah pola regex Anda menjadi " foobar$"bukan hanya foobar.
Umang
Itu benar. Kesalahan saya, dalam sistem saya tidak ada garis dengan 0, tetapi itu harus menjadi kejadian langka. Saya memperbarui jawabannya untuk berjaga-jaga.
Javier Rivera
2

Setelah banyak googling, saya berhasil menyusun skrip ini. Ini berfungsi dengan baik untuk saya:

# List of all packages currently installed
current=$(dpkg -l | awk '{print $2}' | sort | uniq)

# List of all packages that were installed with the system
pre=$(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort | uniq)

# List of packages that don't depend on any other package
manual=$(apt-mark showmanual | sort | uniq)

# (Current - Pre) ∩ (Manual)
packages=$(comm -12 <(comm -23 <(echo "$current") <(echo "$pre")) <(echo "$manual") )

for pack in $packages; do
    packname=$(echo $pack | cut -f 1 -d ":")
    desc=$(apt-cache search "^$packname$" | sed -E 's/.* - (.*)/\1/')
    date=$(date -r /var/lib/dpkg/info/$pack.list)

    echo "# $desc"
    echo "# $date"
    echo "sudo apt-get install $pack"
    echo -e ""
done
dufferZafar
sumber
Anda bisa menggunakan sort -ubukan sort | unique. Karena apt-marktidak menampilkan arsitektur, Anda harus menghapusnya dari output dpkg sebelum operasi yang ditetapkan (atau digunakan dpkg-query -W -f='${Package}\n'). Selain itu, dpkg dapat mendaftar beberapa paket yang tidak diinstal saat ini. Sedangkan untuk "desc", Anda bisa menggunakan `dpkg-query -W -f = '# $ {binary: Summary} \ n' $ pack, yang lebih cepat.
jarno
Oh, apt-markmungkin menampilkan arsitektur untuk beberapa paket, tetapi tidak untuk banyak orang dpkg -l.
jarno
apt-cache searchlambat. Mendapatkan daftar tanggal yang terinstal di muka menggunakan sesuatu seperti help.ubuntu.com/community/ListInstalledPackagesByDate mungkin lebih efisien
opticyclic
1

Seperti kata Li Lo, apt-mark showautoseharusnya Anda mendapat daftar hal-hal yang diinstal secara otomatis.

Sekarang untuk menunjukkan hal-hal yang diinstal secara manual, ternyata ada pengubah pencarian sederhana yang bagus untuk aptitude. Tetapi Anda tidak ingin melakukan itu. Anda ingin menulis perintah bash besar yang melakukan beberapa ilmu roket.

Catatan: Ini lebih merupakan ilustrasi betapa kerennya Anda akan terlihat menerobos perintah bash besar untuk semua teman Anda.

comm -3  <(dpkg-query --show -f '${Package} ${Status}\n' | \n
grep "install ok installed" | cut --delimiter=' ' -f 1) <(apt-mark showauto)

Saya memecahnya menjadi dua baris untuk dibaca. Apa fungsinya?

  • Pertama, kami meminta dpkg untuk daftar paket yang diinstal.
  • Kami memfilternya untuk yang benar-benar diinstal (bukan hanya konfigurasi residu)
  • Kami memotong status
  • Kami membandingkan daftar itu dengan daftar otomatis dari apt-mark
  • Kami mengguncang karena kami bisa.
Oli
sumber
Saya ragu ini akurat, karena dpkg sering menunjukkan paket yang tidak diinstal
txwikinger
Saya tahu apa yang Anda maksud tetapi bash-fu saya tidak cukup kuat. Saya tahu Anda bisa menampilkan status dari dpkg-query, ambil yang turun lalu potong statusnya. Saya akan mencoba.
Oli
comm -3 <(dpkg -l | grep '^ii' | cut -d \ -f 3|sort) <(apt-mark showauto|sort)lebih baik;)
LassePoulsen
-1

Ini akan mencantumkan semua paket yang diinstal secara manual tanpa: dependensi, paket yang dihapus, paket yang diinstal selama instalasi sistem.

unopts() {
  in=`cat`
  echo "$in" | sed -r 's/ --[^ ]+//g;s/ -[^ ]+//g'
}

list() {
  cat '/var/log/apt/history.log' |
  grep --color=never -v '\-o APT::Status-Fd=4 \-o APT::Keep-Fds::=5 \-o APT::Keep-Fds::=6' |
  egrep --color=never "Commandline: apt-get.* $1" |
  sed -r "s/Commandline: apt-get//;s/ $1//" |
  unopts |
  tr ' ' '\n' |
  sed '/^$/d'
}

hapt() {
  tmp=`mktemp -d`
  installed=$tmp/installed
  deleted=$tmp/deleted
  dpkg=$tmp/dpkg
  list 'install' > $installed
  list '(remove|purge|autoremove)' > $deleted
  dpkg --get-selections |
  grep -v 'deinstall' |
  cut -f 1 > $dpkg
  while read package
  do
    sed -i "0,/$package/{//d;}" $installed
  done < $deleted
  while read package
  do
    if [ -z "`grep --color=never "^$package$" $dpkg`" ]
    then
      sed -i "0,/$package/{//d;}" $installed
    fi
  done < $installed
  cat $installed
  rm -r $tmp
}
wieczorek1990
sumber