Generowanie listy ręcznie zainstalowanych pakietów i sprawdzanie poszczególnych pakietów

183

Chciałbym uzyskać listę pakietów zainstalowanych ręcznie przez aptlub aptitudemóc dowiedzieć się, czy foobarpakiet został zainstalowany ręcznie czy automatycznie. Czy jest jakiś fajny sposób na zrobienie tego z wiersza poleceń?

Umang
źródło
Zobacz tę odpowiedź na unix.stackexchange.com, aby znaleźć rozwiązanie, które odfiltrowuje paczki magazynowe.
Dirk Bergstrom
Możliwy duplikat? - askubuntu.com/questions/365
jrg
Bardzo dobre rozwiązanie, które wyklucza pakiety zainstalowane domyślnie: lista zainstalowanych pakietów Ubuntu wyraźnie
PCWorld
Uważaj na komentarze tutaj. Ludzie nie twierdzą, że pojawia się więcej pakietów, ale zapominają, że istnieją pakiety zależności instalowane z instalacji ręcznej.
Andre Figueiredo

Odpowiedzi:

206

Możesz użyć jednej z tych dwóch linijek. Oba dają dokładnie taką samą wydajność na moim komputerze i są bardziej precyzyjne niż wszystkie rozwiązania proponowane do tej pory (6 lipca 2014 r.) W tym pytaniu.

Używanie apt-mark:

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

Używanie 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)

Bardzo niewiele pakietów wciąż przechodzi przez pęknięcia, chociaż podejrzewam, że są one faktycznie instalowane przez użytkownika, albo bezpośrednio po instalacji poprzez konfigurację lokalizacji języka lub np. Przez instalator kodeków Totem. Wydaje się, że również wersje nagłówka linuxa kumulują się, mimo że zainstalowałem tylko niespecyficzny dla metapakietu pakiet. Przykłady:

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

Jak to działa:

  1. Uzyskaj listę ręcznie zainstalowanych pakietów. Dla umiejętności, dodatkowe sedusuwa pozostałe białe znaki na końcu linii.
  2. Pobierz listę pakietów zainstalowanych zaraz po nowej instalacji.
  3. Porównaj pliki, wypisz tylko te wiersze w pliku 1, których nie ma w pliku 2.

Inne możliwości również nie działają:

  • Używanie ubuntu-14.04-desktop-amd64.manifestpliku ( tutaj dla Ubuntu 14.04) zamiast /var/log/installer/initial-status.gz. Więcej pakietów jest wyświetlanych jako zainstalowane ręcznie, nawet jeśli nie są.
  • Używanie apt-mark showautozamiast /var/log/installer/initial-status.gz. apt-markna przykład nie zawiera pakietu xserver-xorg, podczas gdy drugi plik tak.

Użyłem różnych innych postów StackExchange jako odniesień, jednak żadne nie działa tak dobrze, jak powyższe rozwiązanie:

Oba wyświetlają więcej pakietów niż powyższe rozwiązanie.

EDYCJA: Co zrobić, jeśli uaktualniono z poprzedniej wersji:

Jeśli uaktualniłeś system Ubuntu z jednej wersji do drugiej, prawdopodobnie będziesz musiał dostosować ten proces. W takim przypadku sprawdziłbym plik manifestu nowszej wersji (patrz wyżej) oprócz pliku initial-status.gz z bieżącej wersji. Możesz to łatwo zrobić, dodając kolejne porównanie. Używanie samego pliku manifestu nie będzie działać, ponieważ plik manifestu niestety nie zawiera wszystkiego, co robi plik initial_status.gz (sprawdziłem).

jmiserez
źródło
7
To nie działało dla mnie, ponieważ /var/log/installer/initial-status.gzbrakuje. Chcę też wiedzieć, czy to zależy od oznaczenia apts manualczy nie?
Anwar
1
Niestety nie ma manifestu dla wersji serwerowych.
Antti Haapala,
Uruchomiłem showmanualpolecenie (poniżej). I użyj commdo porównania dwóch (posortowanych) list. showmanualWynik dał mi 1.840 bardziej unikalne pakiety z apt-mark showmanualnie pokazane za pomocą tej metody. commŻadne pakiety nie były unikalne dla wyjścia tej komendy. Myślę, że bardziej interesujące jest odnotowanie, że dla mojego komputera 894 pakiety są wymienione w obu wynikach. Nie jestem pewien, dlaczego istnieje tak ogromna rozbieżność. Niektóre (wiele?) Pakiety wydają się być specyficzne dla wydania. Inne, takie jak XOrg, komponenty GTK i lib*rzeczy mogą być aktualizacjami. W każdym razie ta odpowiedź jest bardzo dobrym początkiem.
będzie
Właśnie porównałem twoje rozwiązania apt-mark showmanual. Ciekawe, ile różnic jest widocznych. twoja lista zawiera 238 pakietów, a showmanual zwraca 1717 pakietów. Z 2179 zainstalowanych pakietów, jest tylko 223 na obu listach, 15 jest tylko u ciebie (przykłady: nodejs, lightdm), a 223 tylko w showmanual (przykłady: xserver-xorg, ubuntu-desktop). Wygląda na to, że twoja lista jest bardziej pomocna, ale nie wiedząc, skąd biorą się te różnice, nie jest łatwo zdecydować ... (ale jestem pewien, że ręcznie zainstalowałem nginx i lightdm ...) [przepraszam, że właśnie napisałem to samo;)]
Daniel Alder
64

W nowszych wersjach pakietu apt istnieje także polecenie apt-mark

apt-mark showmanual
Daniel Alder
źródło
35
To pokazuje znacznie więcej pakietów niż zainstalowałem ręcznie.
Umang,
1
@Umang Masz rację. Powiedziałbym, że tak nie było, kiedy napisałem tę odpowiedź. W moim systemie nie ma powodu, aby traktować linux-image-3.11.0-*-genericitp. Jako podręcznik
Daniel Alder
1
@Umang może to pomoże ci askubuntu.com/questions/432743/... , ale odpowiedź nie zostanie zaakceptowana. Faktem jest, że wiele pakietów nowej instalacji jest już oznaczonych jako ręczne. Ale wciąż istnieją dziwne rzeczy. Pozostając z moim przykładem: linux-image-3.13.0-24-genericjest ręczny, ale prąd linux-image-3.13.0-27-genericjest automatyczny. Wygląda na to, że po uaktualnieniu pakietu referencyjnego (w tym przypadku linux-image-generic, który zmienił zależności), znak ręczny jest ustawiany automatycznie
Daniel Alder
5
@Daniel Wcześniej niektóre pakiety nowej instalacji należy oznaczyć jako ręczne. Jeśli żaden pakiet nie zostanie oznaczony jako ręczny, cały system można usunąć za pomocą apt-get autoremove. To zdecydowanie nie jest to, czego chcesz.
Anton K
2
Jeśli „zainstalowany ręcznie” oznacza „zainstalowany przez użytkownika po początkowej instalacji systemu operacyjnego”, nie jest to poprawna odpowiedź.
Seamus
21

W przypadku Ubuntu 16.04 sprawdź plik dziennika /var/log/apt/history.log.

Na przykład:

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

Nie jest idealny, ale całkiem dobrze wyjaśnia, co dokładnie zainstalowałem ręcznie. Umieść -B 1grep, aby zobaczyć, kiedy został zainstalowany.

Przykładowe dane wyjściowe

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

Nie jestem pewien, czy to odbierze, aptitudeczy nie. Wydaje się, że nie pobiera instalacji z aplikacji komputerowej Ubuntu Software.

s1037989
źródło
1
Ze wszystkich odpowiedzi na przestrzeni lat jest to jedyna, która jest bliska serwerowi 18.04.
Quentin Skousen
20

apt-mark showauto | grep -iE '^foobar$' wyświetli „foobar”, jeśli pakiet został zainstalowany automatycznie, nic poza tym.

aptitude search '!~M ~i'wyświetli listę pakietów, które nie zostały zainstalowane automatycznie. Szkoda, że ​​aptitude nie będzie częścią domyślnej instalacji Ubuntu Desktop od 10.10.

Li Lo
źródło
aptitude searchpokazuje WSZYSTKIE pakiety, nie tylko te, które są instalowane ręcznie (zakładam, że tego właśnie chciał OP)
Oli
1
@Oli: spójrz na wzorce wyszukiwania umiejętności; wzór, którego tam używam, powinien robić dokładnie to, czego chce OP.
Li Lo,
I pobiegł go. Pokazuje cały ładunek pakietów, które nie zostały zainstalowane.
Oli
7
Coś jest nie tak z tym, używam aptitude search '!~M ~i'i zawiera listę 1043 pakietów. Nie ma mowy, żebym zainstalował tak wiele pakietów ręcznie.
ThatGraemeGuy
To zdecydowanie nie działa zgodnie z życzeniem, drukuje również wstępnie zainstalowane pakiety.
Irfy,
9

Poniższy skrypt wydrukuje wszystkie pakiety, które nie są ustawione na automatyczną instalację, a zatem zostały zainstalowane ręcznie:

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

opiera się na tym, jak apt-mark wypisuje automatycznie zainstalowane pakiety.

txwikinger
źródło
Uznanie dla pana, proszę pana. To faktycznie działa, w przeciwieństwie do przyjętej odpowiedzi.
Irfy,
pokaż mi tylko kilka paczek - zdecydowanie brakuje mi ich wielu.
Rmano
To samo tutaj, zdecydowanie brakuje ręcznie zainstalowanych pakietów, zaraz po ich zainstalowaniu.
David Ljung Madison
Używanie sys.exit(1)bez import sysmoże spowodować błąd w nowszych wersjach Pythona. Albo import sysalbo użyj exit(1).
Videonauth
7

Aby uzyskać listę wszystkich pakietów (niezainstalowanych, zainstalowanych przez użytkownika lub domyślnie zainstalowanych we wszystkich PPA), aptstosuje się następującą metodę:

apt list [option]

Możliwe przydatne opcje to:

--installed wyświetlać tylko pakiety zainstalowane w systemie (spośród ponad 50 000)

--manual-installedaby wyświetlić listę pakietów, które zostały jawnie zainstalowane przez polecenie, bezpośrednio lub jako zależności.

Alternatywnie możesz zrobić:

apt list --manual-installed | grep -F \[installed\] aby uzyskać listę pakietów, które wynikają wyłącznie z poleceń użytkownika i ich zależności, oraz uzyskać dodatkowe informacje na ich temat, takie jak obsługiwana wersja i architektura (x86, x86_64, amd64, wszystkie itp.)

Aalok
źródło
5

Jak skomentowało kilka osób, showmanual apt-mark wydaje się nieco wadliwy (i zgłosiłem to jako błąd 727799 ). Kiedy go używam, w rzeczywistości zgłasza wiele rzeczy, które nawet nie są zalogowane / var / lib / apt / Extended_states (gdzie to powinno być przechowywane), a apt-get nie rejestruje rzeczy jako zainstalowanych w / var / lib / apt / Extended_states (tylko w / var / lib / dpkg / status). Skrypt Pythona autorstwa powyższego txwikinger czerpie bezpośrednio z / var / lib / apt / Extended_states, ale jeśli go używasz dzisiaj, składnia może nie działać (moje właśnie zaczęło generować błędy w Kubuntu 13.10). Zaktualizowana składnia to:

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

Dla mnie była to bardzo krótka lista 5 pozycji, która również nie wydaje się dokładna.

cluelesscoder
źródło
1
Używanie sys.exit(1)bez import sysmoże spowodować błąd w nowszych wersjach Pythona. Albo import sysalbo użyj exit(1).
Videonauth
4

Chciałbym podać rozwiązanie GUI.

wprowadź opis zdjęcia tutaj

  1. otwarty Synaptic Package Manager

  2. Iść do Status

  3. Kliknij Installed (manual)

Podaje listę pakietów instalowanych ręcznie przez apt lub aptitude.

Niestety nie mogłem znaleźć żadnej opcji, Custom Filtersaby dowiedzieć się, czy foobarpakiet został zainstalowany ręcznie czy automatycznie.

Jeśli pakiet jest pod, Installedale nie pod, oznacza Installed (manual)to, że został zainstalowany automatycznie. Jeśli pakiet jest poniżej, Installed (manual)to został zainstalowany ręcznie.

Blue Ray
źródło
2

Jeśli nikt nie daje piękny odpowiedź za pomocą polecenia APR-coś można zrobić to w przykry sposób . Apt-get przechowuje informacje w / var / lib / apt / Extended_states. Każdy plik instalowany automatycznie zostanie dodany do tego pliku. Jeśli zainstalujesz pakiet już w tym pliku ręcznie, pakiet pozostanie w tym pliku, ale z Autoinstalacją: 0 w drugim wierszu. Nie jest usuwany.

Uwaga: zgodnie z oczekiwaniami lepsze odpowiedzi, które mogą zadziałać, jeśli pojawią się zmiany umieszczania plików. Przechowuję moje na wypadek, gdyby informacje o lokalizacji pliku były przydatne.

Javier Rivera
źródło
1
Nie. Rzuciłem okiem na ten plik, aby stwierdzić, że liferea została oznaczona jako automatycznie zainstalowana. Zrobiłem apt-get install lifereai nie został zainstalowany, ale otrzymałem wynik, który był efektem „oznaczono jako zainstalowany ręcznie”. Teraz liferea jest nadal w pliku, z wyjątkiem tego, że następny wiersz zawiera 0zamiast 1. Powinieneś także zmienić wzorzec wyrażenia regularnego na " foobar$"zamiast po prostu foobar.
Umang,
To prawda. Moja wina, w moim systemie nie ma linii z 0, ale zdarza się to rzadko. Aktualizuję odpowiedź na wszelki wypadek.
Javier Rivera,
2

Po wielu wyszukiwaniach udało mi się skompletować ten skrypt. Dla mnie to działa dobrze:

# 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
źródło
Możesz użyć sort -uzamiast sort | unique. Ponieważ apt-marknie wyświetla architektury, należy usunąć ją z danych wyjściowych dpkg przed ustawieniem operacji (lub użyciem dpkg-query -W -f='${Package}\n'). Poza tym dpkg może wyświetlać niektóre pakiety, które nie są obecnie zainstalowane. Jeśli chodzi o "desc", możesz użyć pakietu `dpkg-query -W -f = '# $ {binary: Summary} \ n' $ pack, który jest szybszy.
jarno,
Och, apt-markmoże wyświetlać architekturę dla niektórych pakietów, ale nie dla wielu dpkg -l.
jarno
apt-cache searchjest wolny. Uzyskiwanie listy zainstalowanych dat z góry za pomocą czegoś takiego jak help.ubuntu.com/community/ListInstalledPackagesByDate może być bardziej wydajne
opticyclic
1

Jak powiedział Li Lo, apt-mark showautopowinienem uzyskać grubą listę rzeczy automatycznie instalowanych.

Teraz, aby pokazać rzeczy, które są instalowane ręcznie, okazuje się, że istnieje piękny prosty modyfikator wyszukiwania dla aptitude. Ale nie chcesz tego robić. Chcesz napisać wielkie polecenie bashowe, które robi naukę o rakietach.

Uwaga: To bardziej ilustruje, jak fajnie będziesz wyglądać, wydając masowe polecenia bash wszystkim znajomym.

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

Podzieliłem go na dwie linie dla czytelności. Co to robi?

  • Najpierw pytamy dpkg o listę zainstalowanych pakietów.
  • Filtrujemy je według tych, które są faktycznie zainstalowane (nie tylko resztkowa konfiguracja)
  • Odcinamy status
  • Porównujemy tę listę z listą automatyczną z apt-mark
  • Rozkołysamy się, ponieważ możemy.
Oli
źródło
Wątpię, aby było to dokładne, ponieważ dpkg często pokazuje pakiety, które nie są zainstalowane
txwikinger
Wiem, co masz na myśli, ale mój bash-fu nie jest wystarczająco silny. Wiem, że możesz pokazać status z dpkg-query, grep to w dół, a następnie odciąć status. Spróbuję.
Oli
comm -3 <(dpkg -l | grep '^ii' | cut -d \ -f 3|sort) <(apt-mark showauto|sort)jest odpowiednio lepszy;)
LassePoulsen
-1

Spowoduje to wyświetlenie wszystkich ręcznie zainstalowanych pakietów bez: zależności, odinstalowanych pakietów, pakietów zainstalowanych podczas instalacji systemu.

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
źródło