शीर्ष स्तर को मैन्युअल रूप से स्थापित पैकेजों पर उनकी निर्भरता के बिना सूचीबद्ध करें


12

मैन्युअल रूप से इंस्टॉल किए गए पैकेज दिखाने के कई तरीके हैं apt, जैसे:

apt-mark showmanual

लेकिन कभी-कभी वह आउटपुट बहुत अधिक होता है। उदाहरण के लिए यदि उपयोगकर्ता मैन्युअल रूप से स्थापित पैकेज foo:

apt-get install foo

... और fooपर निर्भर barहै और bazहै, तो apt-mark showmanualउत्पादन होगा:

bar
baz
foo

कैसे हम केवल शीर्ष स्तर मैन्युअल इंस्टॉल किए गए पैकेज (सूचीबद्ध कर सकते हैं यानी foo ) उनकी निर्भरता के बिना ( यानी नहीं baz, और न ही bar)?


निम्न कोड काम करने लगता है, लेकिन कुछ सौ बार कॉल करने वाला GNU बहुत धीमा है, (4 कोर सीपीयू के साथ तीन घंटे):parallelapt-rdepends

apt-mark showmanual | 
tee /tmp/foo | 
parallel "apt-rdepends -f Depends,PreDepends,Suggests,Recommends {} |
          tail +2" 2> /dev/null | 
tr -s ' ' '\n' | 
grep -v '[():]' | 
sort -Vu | 
grep -wv -f - /tmp/foo

हम्म। उत्तर, और ओपी कोड, सभी इतने अलग हैं, और कुछ अलग डेटा लौटाते हैं, कि मुझे थोड़ा फजी हो रहा है कि किस विधि का डेटा सबसे सही है। शायद एक सर्वेक्षण उत्तर की आवश्यकता है, न्यूनतम परीक्षण प्रणाली से शुरू करना, और आउटपुट को कैसे और कब भिन्न होता है यह देखने के लिए एक समय में कुछ प्रोग्राम जोड़ना।
Agc

जवाबों:


9

यह पायथन एप एपीआई का उपयोग करके किया जा सकता है। आपके द्वारा देखे जाने वाले पैकेज apt-mark showmanualवास्तव में वही हैं apt.cache.Cache()जिनके is_installedलिए सत्य है और is_auto_installedगलत है। लेकिन, निर्भरता को संसाधित करना आसान है:

#! /usr/bin/env python3

from apt import cache

manual = set(pkg for pkg in cache.Cache() if pkg.is_installed and not pkg.is_auto_installed)
depends = set(dep_pkg.name for pkg in manual for dep in pkg.installed.get_dependencies('PreDepends', 'Depends', 'Recommends') for dep_pkg in dep)

print('\n'.join(pkg.name for pkg in manual if pkg.name not in depends))

यहां तक ​​कि यह कुछ पैकेजों को सूचीबद्ध करता है जिन्हें मैं वहां ( init, grep?) देखने की उम्मीद नहीं करूंगा ।


मेरे सिस्टम पर वह कोड मेरे 3-घंटे के कोड के एक सुपरसेट को आउटपुट करता है, लेकिन जैसे कोई आश्चर्य नहीं दिखाता है initऔर grep(शायद आपका डेटा ख़राब है?), यह बहुत सारे पुस्तकालयों को भी दिखाता है। OTOH, मेरा 3-घंटे का कोड कुछ वस्तुओं को याद करता है जो वहाँ होनी चाहिए, वे आइटम जो उपरोक्त pythonकोड प्रिंट करते हैं। संभवतः गायब आइटम के साथ स्थापित नहीं थे apt
अगस्त

@agc शायद ऐसा इसलिए है क्योंकि मैं दोबारा नहीं आया। मैं सप्ताहांत के बाद एक पुनरावर्ती विकल्प का प्रयास करूँगा। यहां तक कि प्रत्यावर्तन के साथ, हालांकि, मैं इस बुला तुलना में तेजी से रास्ता उम्मीद थी बार-बार apt-rdepends
muru

pythonमेरे कोड (3 घंटे) की तुलना में उपरोक्त कोड 3600 गुना तेज है (यानी इसमें 3 सेकंड का समय लगा)। पुनरावर्ती संस्करण का परीक्षण करने के लिए उत्सुक ...
एजी

3

निम्न शेल स्क्रिप्ट सभी स्थापित निर्भरताओं के माता-पिता के लिए खोज करता है।

function get_installed_packages() {
    apt list --installed | sed 's#/.*##'
}

function get_installed_packages_with_deps() {
    dpkg-query --show --showformat '${Package} ${Depends} \
        ${Pre-Depends}\n' $(get_installed_packages) | 
    sed 's/ ([^(]*)//g; s/:any\|,//g'
}

function get_package_relations() {
    awk '{print $1 " " $1; for(i = 2; i <= NF; i++) print $1 " " $i;}'
}

function add_marker() {
    echo "~ ~"
}

function resolve_parents() {
    tsort | sed -n '1,/~/ p' | head -n -1
}

(get_installed_packages_with_deps | get_package_relations; add_marker) | 
resolve_parents

मैंने tsortइस स्क्रिप्ट में इस्तेमाल किया । मुझे लगता है कि जब निर्भरता के बिना अंत में एक मार्कर जोड़ते हैं तो मार्कर मेरे परिणाम में निर्भरता के बिना अंतिम प्रविष्टि भी होगा। तो मैं निर्भरता के बिना पिछले पैकेज और depenencies के साथ पहले पैकेज के बीच अंतर कर सकते हैं।

मैंने इस समाधान के साथ एक समस्या पर ध्यान दिया:
निर्भरता ग्राफ में चक्र हैं। उन प्रविष्टियों को नजरअंदाज कर दिया जाता है tsort


2

आप निम्न प्रकार से निर्भरता के अपने स्तर के बिना सभी मैन्युअल रूप से स्थापित पैकेज पा सकते हैं:

apt-mark showmanual | sort > manually-installed.txt

apt show $(apt-mark showmanual) 2>/dev/null | 
grep -e ^Depends -e ^Pre-Depends > deps1.txt

cat deps1.txt | 
sed 's/^Depends: //; s/^Pre-Depends: //; 
     s/(.*)//g; s/:any//g' > deps2.txt

cat deps2.txt | tr -d ',|' | tr ' ' '\n' | grep -v ^$ |
sort -u > all-dep-packages.txt

grep -v -F -f all-dep-packages.txt manually-installed.txt

आप निम्नलिखित एक-लाइनर जादू का उपयोग भी कर सकते हैं:

apt-mark showmanual | sort | grep -v -F -f <(apt show $(apt-mark showmanual) 2> /dev/null | grep -e ^Depends -e ^Pre-Depends | sed 's/^Depends: //; s/^Pre-Depends: //; s/(.*)//g; s/:any//g' | tr -d ',|' | tr ' ' '\n' | grep -v ^$ | sort -u)

काफी तेज। यह आउटपुट जो ज्यादातर ओपी कोड का एक सुपरसेट होता है, लेकिन यह dasherपैकेज जैसे कुछ को भी याद करता है। अपने सिस्टम पर ओपी कोड के माध्यम से पहुंचाया sort -Vआउटपुट 475 लाइनों, muru का कोड आउटपुट 914 लाइनों, (सहित dasher), और इस उत्तर के कोड आउटपुट 995 लाइनों।
11

हां, मेरी स्क्रिप्ट पूरी तरह से निर्भरता का पेड़ नहीं है। आप इसे अधिक पदानुक्रम स्तरों के लिए अनुकूलित करने का प्रयास कर सकते हैं।
मुहर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.