คำสั่ง 'apt-get remove' นี้ทำอะไร?


10

รหัสต่อไปนี้ทำอะไร?

ฉันพบมันบนอินเทอร์เน็ตดังนั้นฉันจึงคัดลอกและวางลงในเทอร์มินัล แต่เมื่อฉันติดตั้งเคอร์เนลใหม่มันจะตรวจจับสิ่งเก่าเท่านั้น

sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')

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

รหัสนี้จะไม่ติดตั้งเคอร์เนลใด ๆ แต่ลบออก ! ฉันไม่เห็นว่าสิ่งนี้ sed คำสั่งไม่ แต่จะประมวลผลการส่งออกของ ซึ่งจะแสดงรายการแพคเกจเคอร์เนลที่ติดตั้งทั้งหมดและตัวกรองบางส่วนของพวกเขาออกสำหรับการลบโดยdpkg -l 'linux-image-*' apt-get remove
ผู้บัญชาการ Byte

16
กฎง่ายๆที่ควรปฏิบัติหากคุณไม่รู้ว่าโค้ดทำอะไรอย่าวางโค้ดนั้นไว้ใน Terminal จนกว่าจะมีคนที่รู้ว่าโค้ดบอกอะไรคุณ หากคุณพยายามรับเคอร์เนลที่ทันสมัยที่สุดคุณอาจต้องการดูaskubuntu.com/questions/119080//แทนการใช้รหัสที่คุณไม่เข้าใจ
พันเอก Trogdor

เมล็ดเก่านั่งอยู่รอบ ๆ ดิสก์ทำให้ไม่มีปัญหายกเว้นการกินพื้นที่ดิสก์และทำให้update-grubแพคเกจโพสต์ช้าลง หากคุณกังวลว่าคุณไม่ได้ทำการบูตเคอร์เนลที่คุณพยายามอัพเกรดมาให้ทำงานuname -aหรือแม้กระทั่งdmesg | less
Peter Cordes

7
"ฉันพบมันบนอินเทอร์เน็ตดังนั้นฉันจึงคัดลอกและวางลงในเทอร์มินัล" ไม่ไม่ไม่ไม่ไม่ คุณจะต้องทำสิ่งที่น่ากลัวโดยไม่ได้ตั้งใจ ใช้รหัสคุณไม่เข้าใจผลลัพธ์ในสิ่งที่น่ากลัวเช่น nuking ระบบของคุณและลูกสุนัขที่ถูกเตะ
Geek

คำตอบ:


12

มาแบ่งรหัสทีละหนึ่ง (สำหรับระบบของฉัน):

$ dpkg -l 'linux-image-*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                          Version             Architecture        Description
+++-=============================-===================-===================-================================================================
un  linux-image-3.0               <none>              <none>              (no description available)
ii  linux-image-3.13.0-32-generic 3.13.0-32.57        amd64               Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-g 3.13.0-32.57        amd64               Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic           3.13.0.32.38        amd64               Generic Linux kernel image


$ dpkg -l 'linux-image-*' | sed '/^ii/!d'
ii  linux-image-3.13.0-32-generic                         3.13.0-32.57                                        amd64        Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-generic                   3.13.0-32.57                                        amd64        Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image


$ uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/'
3.13.0-32



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d"
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/'
linux-image-generic



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | sed '/[0-9]/!d'
## No output

ดังนั้นจะไม่ทำอะไร:

$ sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')

อย่างที่คุณเห็นมันใกล้เคียงกับการลบแพ็คเกจเมตาแกรมปัจจุบันของฉัน linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (ขอบคุณsed '/[0-9]/!d'บรรทัดสุดท้ายนี้) ซึ่งผิด

โดยสังเขปชิ้นนี้sedมีหลายประเด็น คุณควรหลีกเลี่ยงที่จะลบเมล็ดเก่าออก

แก้ไข:

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

สองบรรทัดสุดท้ายในรูปแบบที่แก้ไข:

sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|-)*)\..*/\1-\4\3/'

ดังนั้น:

$ dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | 
sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/'

Outpus:

linux-image-3.13.0.32-generic

นั่นมันช่างเลวร้ายมาก !!

ตอนนี้แสดงสิ่งนี้จะทำอะไรกับระบบของฉัน--dry-running apt-get removeคำสั่งเต็ม:

$ sudo apt-get remove --dry-run $(dpkg -l 'linux-image-*' | 
sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/')


Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'linux-image-3.13.0-32-generic' for regex 'linux-image-3.13.0.32-generic'
The following package was automatically installed and is no longer required:
  linux-headers-generic
Use 'apt-get autoremove' to remove it.
The following packages will be REMOVED:
  linux-generic linux-image-3.13.0-32-generic
  linux-image-extra-3.13.0-32-generic linux-image-generic
0 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Remv linux-generic [3.13.0.32.38]
Remv linux-image-generic [3.13.0.32.38]
Remv linux-image-extra-3.13.0-32-generic [3.13.0-32.57]
Remv linux-image-3.13.0-32-generic [3.13.0-32.57]

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

** หมายเหตุว่ารหัสที่เกิดขึ้นจริงจะทำงานถ้าทำrebootหลังจากการปรับรุ่นเคอร์เนลเป็นOli กล่าวแล้ว

EDIT2:

นี่เป็นสคริปต์ที่เรียบง่าย แต่มีประสิทธิภาพที่จะพิจารณาทุกสถานการณ์และลบเมล็ดเก่าที่แท้จริง:

#!/bin/bash
kernels=( $(grep -Po "^linux-image-[^-]+-[^-]+-generic\b" < <(dpkg --get-selections)) )
cur_rel=$(grep -Po ".*(?=-[a-z]*$)" < <(uname -r))

for kernel in "${kernels[@]}"; do
    ker_rel=$(grep -Po "[0-9].*(?=-[a-z]*)" <<< "$kernel")
    dpkg --compare-versions "$ker_rel" gt "$cur_rel" && { echo "Please Restart your computer first"; break; }
    dpkg --compare-versions "$ker_rel" lt "$cur_rel" && sudo apt-get remove "$kernel"
done

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


อืมรออะไรนะ คุณแทนที่รหัสเดิมที่ใช้งานได้ด้วยรหัสอื่นที่คุณคิดว่า "ควรจริง (!!) อยู่ที่นั่น" สังเกตว่ารหัส "คงที่" ของคุณเสียและจะลบเคอร์เนลปัจจุบันของคุณและทำให้สรุปได้ว่ารหัสเดิมคือ " บ้าบิ่นมาก !! "? WTF? -1
Ilmari Karonen

มีเหตุผลที่ถูกต้องอย่างแน่นอนที่จะวิพากษ์วิจารณ์รหัสต้นฉบับตามที่ระบุไว้เช่นในคำตอบของ Oli และฉันมั่นใจว่ารหัส sed อาจจะแข็งแกร่งกว่านี้ได้ แต่ความจริงนั้นยังคงอยู่ภายใต้สถานการณ์ปกติ (เช่นคุณรีบูตเครื่องหลังจากอัพเกรดเคอร์เนลครั้งสุดท้าย) รหัสต้นฉบับจะทำงานได้ในขณะที่เวอร์ชันที่คุณแก้ไขไม่ทำงาน
Ilmari Karonen

1
ก่อนอื่นคุณไม่ควรใช้คำสุดท้ายที่คุณเคยใช้มาตอนนี้คุณเรียกใช้รหัสจริงหรือไม่? เอาชิ้นapt-getส่วนออกและเอาท์พุทอะไรที่คุณได้รับ?
heemayl

@IlmariKaronen: ดีฉันสองกับคุณในบางจุดที่ผมได้แก้ไขคำตอบ ..
heemayl

ทำไมใช่ฉันไม่เรียกใช้คำสั่งปรับเปลี่ยน (รุ่นที่ไม่ผิดพลาดเนื่องจากวงเล็บหายไปหลังจาก(([a-z]|-)*ที่มี) โดยไม่ต้องapt-getมีส่วนร่วมก่อนที่จะวิจารณ์ linux-image-3.13-ในระบบของฉันมันจะออกผลลัพธ์บรรทัดต่อไปนี้: linux-image-3.13-, linux-image-extra-3.13-, linux-image-extra-3.13-, linux-image-3.13.0.49-generic, ที่เป็นจริงสิ่งที่คุณตั้งใจ? (เช่นเดียวกับคะแนนโบนัสหากคุณสามารถทราบได้ว่าเมล็ดที่ฉันติดตั้งจริง ๆ )
Ilmari Karonen

12

นี่เป็นความพยายามที่จะลบเมล็ดที่ไม่ใช่เมล็ดปัจจุบัน

มีหลายบิตของรหัสออกมีที่ทำอะไรเช่นนี้และนี้มันไม่ได้เป็นตัวอย่างที่ดี มันสามารถลบเมล็ดที่ใหม่กว่ากระแสได้อย่างง่ายดายดังนั้นเมตาแพ็คเกจที่ติดตั้ง ( linux-genericet al) หากคุณมีการอัพเกรดและไม่ได้รีบูต


2
และนี่ไม่ใช่ความคิดที่ดีเลย เมล็ดที่แก่กว่านั้นจะถูกเก็บไว้ด้วยเหตุผลโดยค่าเริ่มต้นมีเพียง 2 อันและอันปัจจุบันเท่านั้น
Barafu Albino
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.