คำสั่งนี้เพื่อลบเมล็ดเก่าปลอดภัยหรือไม่?


21

ในขณะที่ท่องอินเทอร์เน็ตสำหรับบทความ Ubuntu ฉันเจอคำสั่งนี้:

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

ผู้เขียนบอกว่านี่เป็นคำสั่งบรรทัดเดียวซึ่งจะลบ Linux เวอร์ชันก่อนหน้าทั้งหมดออกเหลือเพียงเวอร์ชันปัจจุบันเท่านั้น !

จริง ๆ แล้วฉันกำลังมองหาคำสั่งดังกล่าว แต่ฉันไม่แน่ใจเกี่ยวกับความปลอดภัยนี้ ฉันอยากรู้:

  • ไม่ว่าจะปลอดภัยในการดำเนินการคำสั่งนี้?
  • คำสั่งนี้ทำงานอย่างไร เช่นคำอธิบายชิ้นส่วนเล็ก ๆ ของคำสั่งขนาดใหญ่
  • หากคำสั่งนี้ทำหน้าที่จุดประสงค์ที่แตกต่างกันอะไรคือคำสั่งที่ถูกต้องที่จะบรรลุสิ่งที่ผู้เขียนอ้างว่าทำ

ฉันสับสนและผิดหวังมากเมื่อพยายามอนุมานด้วยตัวเอง วิธีการทำงานคำสั่งนี้ให้มันมีมากมาย/, |, \, *และ^ตัวละครที่ยากแก่ Google สำหรับ

ฉันกำลังมองหาการแปลทีละขั้นตอนและคำอธิบายสำหรับคำสั่งนี้ซึ่งฉันไม่สามารถหาได้จากอินเทอร์เน็ต!


1
ดูเหมือนว่านี่จะไม่ใช่คำสั่งเดียวกับที่คุณอ้าง แต่ฉันได้ใช้คำสั่งในtuxtweaks.com/2010/10//เพื่อลบเมล็ดเก่าโดยไม่มีปัญหาใด ๆ หน้านี้ยังอธิบายสิ่งที่คำสั่งทำ
user68186

4
@UriHerrera apt-get autoremoveไม่แนะนำให้นำเมล็ดเก่าออกให้ฉัน หากฉันไม่ลบพวกเขาพวกเขาจะกองพะเนินเทินทึกจนกว่าฉัน/bootจะออกจากพื้นที่และการปรับปรุงล้มเหลว คุณมีข้อมูลอ้างอิงเกี่ยวกับสิ่งที่ควรทำหรือไม่
gertvdijk

1
มันทำให้ฉันเมื่อใดก็ตามที่มีการปรับปรุงใหม่สำหรับเคอร์เนลมันบอกว่าภายหลังแพคเกจต่อไปนี้ ฯลฯ ไม่จำเป็นอีกต่อไปและมันจะแสดงรายการเคอร์เนลก่อนหน้านี้ที่ฉันมี
Uri Herrera

คำตอบของฉันถูกลบโดยโมเดอเรเตอร์ดังนั้นฉันจึงแสดงความคิดเห็นที่นี่: ดูบทความนี้สำหรับคำอธิบายของสคริปต์ ผมไม่เห็นว่าทำไมส่วนหนึ่งของสคริปต์แทนที่จะs/^[^ ]* [^ ]* \([^ ]*\).*/\1/ s/^[^ ]* \([^ ]*\).*/\1/สคริปต์ไม่แข็งแรงหรือสวยงามมาก ตัวอย่างเช่นทำไมตรวจสอบเคอร์เนลปัจจุบันก่อนที่จะแตกชื่อแพ็กเกจออกจากเอาต์พุต สำหรับทางเลือกให้sudo apt-get autoremove --purgeล้างเมล็ดข้าวที่เก่าแก่ที่สุดใน Ubuntu รุ่นล่าสุดบางรุ่นเช่น Xubuntu 15.10
jarno

คำตอบ:


27

ฉันจะบอกว่า: อย่าใช้มันในรูปแบบปัจจุบัน

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

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

  3. dpkg -lsudoทำงานได้ดีโดยไม่ต้อง ฉันไม่เห็นว่าทำไมผู้เขียนดั้งเดิมคิดว่ามันจำเป็น

ใช้สามัญสำนึก

นำชิ้นส่วนที่เป็นอันตรายออกและปล่อยสิ่งใดก็ตามที่ทำงานเหมือนราก

ตัวอย่างเช่นตัดลงไปที่:

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

ซึ่งก็เพียงเอาท์พุทสิ่งและทำงานกับสิทธิ์ของผู้ใช้ปกติ เมื่อคุณเห็นด้วยกับการลบเมล็ดเหล่านี้คุณสามารถผนวก | xargs sudo apt-get purgeตัวเอง มันไม่มี-yตัวเลือกโดยเจตนาดังนั้นคุณจะถูกขอให้ยืนยันการเปลี่ยนแปลงที่จะเกิดขึ้นกับระบบของคุณ

คำอธิบาย

  • dpkg -lแสดงรายการของแพ็คเกจทั้งหมด ในกรณีนี้จะแสดงเฉพาะแพ็คเกจที่ขึ้นต้นด้วยlinux-ชื่อ
  • |(ไพพ์) ไพพ์เอาต์พุตของคำสั่งทางด้านซ้าย (เราเรียกมันว่าstdout) ไปยังอินพุตของคำสั่งทางด้านขวา (เราเรียกมันว่าstdin)
  • sedเป็นเครื่องมือในการจัดการกับสายใช้การแสดงออกปกติ ในกรณีนี้มันจัดการเอาท์พุทของคำสั่งทางด้านซ้ายของไพพ์และฟิลเตอร์สำหรับแพ็คเกจที่ติดตั้ง (อาศัยiiตามที่กำหนดโดยdpkg) มันกำลังถูกซ้อนในกรณีนี้ มันจะยากเกินไปที่จะอธิบายการใช้ทั้งหมดของsedที่นี่เนื่องจากการใช้งานมีความซับซ้อนมากกับการแสดงออกปกติที่ซับซ้อน ( \(.*\)-\([^0-9]\+\)"เป็นตัวอย่างของการแสดงออกปกติ
  • นิพจน์ทั่วไปนั้นใช้กันอย่างแพร่หลายมากในการค้นหาการจับคู่ตามนิพจน์ที่แสดง \1เป็นการอ้างอิงทดแทนเพื่อทำการค้นหาและแทนที่แบบสากล (อ้างอิงถึง 'hit' ครั้งแรกด้วย1) การแสดงออกปกติไม่สามารถทำอันตรายใด ๆ ได้ อย่างไรก็ตามหากพวกเขาจัดการอินพุตในทางที่ผิดพวกเขาสามารถให้คุณลบแพ็กเกจที่ไม่ถูกต้องหรือแม้แต่การฉีดเชลล์ ในกรณีนี้ดูเหมือนว่าจะหาชื่อของแพ็กเกจเคอร์เนลตามเวอร์ชั่นที่ให้uname -rมา
  • uname -r แสดงผลรุ่นปัจจุบันของเคอร์เนลที่ทำงาน
  • xargsต่อท้ายบรรทัดของอินพุตทางซ้ายของไพพ์เป็นอาร์กิวเมนต์ของคำสั่ง ในกรณีนี้เวอร์ชันเคอร์เนลในแต่ละบรรทัดจะถูกแปลงเป็นรายการที่คั่นด้วยช่องว่างแนวนอนและผนวกเข้ากับsudo apt-getคำสั่ง
  • sudo apt-get -y purge [packagename] กำจัด (ลบทุกอย่าง) ของแพ็คเกจที่กำหนด (เป็นอาร์กิวเมนต์)

ทางเลือก

คำถามบางอย่างอาจถูกถามเกี่ยวกับเรื่องนี้แล้ว สิ่งที่เกี่ยวข้องที่ฉันพบ:


1
สิ่งที่จะเป็นการกระจัดกระจายของโหนดการค้นหาที่น่ากลัวของคำสั่งนี้ซึ่งเป็นสิ่งที่เช่นนี้ ] * [^] * ([^] *). * / \ 1 /; /
Bhavesh Diwan

คำสั่งที่กล่าวไว้ข้างต้นในคำตอบนี้จะล้างเมล็ดพืชที่สวยงามหรือไม่? หรือยัง apt-get autoremove ดีกว่า
Bhavesh Diwan

4
@ Z9iT นั่นคือการแสดงออกปกติ พวกเขาใช้เพื่อค้นหาการจับคู่ตามนิพจน์ที่พวกเขานำเสนอและ\1เป็นตัวควบคุมการแทนที่เพื่อทำการค้นหาและแทนที่แบบสากล สำหรับการลบแพคเกจใด ๆ ฉันได้แสดงความชัดเจนในคำตอบของฉัน (เป็นความคิดเห็นของฉัน): ใช้สามัญสำนึก อย่าให้สคริปต์เปลี่ยนแปลงระบบของคุณโดยอัตโนมัติ ตรวจสอบสิ่งที่จะทำ เสมอ.
gertvdijk

คุณสมบัติที่คุณเลือกไม่ได้ทำการลบแพ็คเกจ linux-header ที่เกี่ยวข้อง
jarno

จากนั้นเพียงทำการรับอัตโนมัติ apt-get ซึ่งควรตรวจสอบส่วนหัวเหล่านั้นไม่จำเป็นอีกต่อไป
ben-Nabiy Derush

7

คุณขอคำอธิบายทีละขั้นตอนดังนั้นที่นี่ไป:

sudo dpkg -l 'linux-*'

แสดงรายการแพ็กเกจที่เริ่มต้นด้วยlinux-ในชื่อแพ็คเกจ

| sed

และท่อรายการเข้าไป sed

"s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

ซึ่งจะใช้นิพจน์ทั่วไปที่ซับซ้อนมากในการแก้ไขรายการ

| xargs

ซึ่งจะไพพ์รายการใหม่เข้าไปxargsซึ่งจะส่งเป็นอาร์กิวเมนต์ไปยัง

sudo apt-get -y purge

ซึ่งจะกำจัดแพ็คเกจเหล่านั้นโดยไม่ให้โอกาสคุณเปลี่ยนใจ

หรืออาจจะแม่นยำมากกว่าที่จะกล่าวว่าจะส่งรายการนั้นไปยังคำสั่งล้างข้อมูลและปล่อยให้เป็นอย่างนั้น ไม่ว่าจะมีการล้างสิ่งใดหรือไม่ก็ตามและที่สำคัญ - สิ่งที่ถูกลบทิ้งนั้นขึ้นอยู่กับ ouput ของคำสั่งก่อนหน้า

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


6

ฉันเริ่มต้นโดยการแยกคำสั่งอ่านmanหน้าแต่ละรายการ

  • dpkg -l: รายการ pacakges ดังนั้นdpkg -l linux-*จะแสดงรายการแพคเกจทั้งหมดที่เริ่มต้นด้วยlinux-(ปกติจะเป็นเมล็ด)

  • sed: เอาต์พุตของdpkg -l linux-*ถูกไพพ์ไปที่sedหลายนิพจน์ทั่วไปที่sedถอดรหัส

  • uname -r unameพิมพ์ข้อมูลระบบ

uname - ข้อมูลระบบการพิมพ์

-rจับเฉพาะพิมพ์เผยแพร่เคอร์เนล:

-r, --kernel-release พิมพ์การเปิดเคอร์เนล

เอาต์พุตของuname -rถูกไพพ์แล้วsedด้วยนิพจน์ทั่วไปที่มากขึ้นซึ่งส่งออกไปยังxargs

ดังนั้นxargsแปลsedผลลัพธ์เป็นชื่อแพ็กเกจและส่งผ่านไปยังsudo apt-get purge -yซึ่งตอบโดยอัตโนมัติว่า 'ใช่' เพื่อแจ้งทั้งหมด:

-y, - ใช่, - สมมติว่า - ใช่อัตโนมัติใช่เพื่อแจ้งให้; สมมติว่า "ใช่" เป็นคำตอบสำหรับข้อความแจ้งทั้งหมดและเรียกใช้แบบไม่โต้ตอบ หากสถานการณ์ที่ไม่พึงประสงค์เช่นการเปลี่ยนแพคเกจที่มีอยู่พยายามที่จะติดตั้งแพคเกจที่ไม่ได้รับการรับรองหรือการลบแพคเกจที่จำเป็นเกิดขึ้นแล้ว apt-get จะยกเลิก รายการการกำหนดค่า: APT :: Get :: Assume-Yes

โดยสิ้นเชิงดูเหมือนว่าคำสั่งนี้จะทำในสิ่งที่คุณต้องการ แต่ต้องรู้แน่นอนว่าเราต้องแปลsedสำนวนปกติ

ฉันเพิ่งวิ่ง:

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

นี่คือภาพหน้าจอ:

ป้อนคำอธิบายรูปภาพที่นี่

เคอร์เนลเวอร์ชันเก่าทั้งหมด iirc


การออกกำลังกายเพื่อแปลการแสดงออกของ sed นี้คืออะไร?
Bhavesh Diwan

2
ฉันพยายามที่จะเข้าใจมันตอนนี้อาจใช้เวลาในขณะที่เรา;)
เซท

ดูคำตอบของฉัน
jarno

@ Z9iT ฉันขี้เกียจเกินไปที่จะคัดลอกคำอธิบายของสคริปต์จากบทความที่เชื่อมโยงไปยังคำตอบดังนั้นฉันเดาว่านั่นคือสาเหตุที่ Seth ลบคำตอบของฉัน แต่ฉันคิดว่าบทความที่เชื่อมโยงคือสิ่งที่คุณต้องการจากอินเทอร์เน็ต ฉันยังบอกคุณถึงวิธีที่ปลอดภัยกว่าในการลบเมล็ดเก่าออกไปแม้ว่ามันจะเก็บเมล็ดไว้ 2-3 อันในกรณีและอาจไม่สามารถใช้งานได้ใน Ubuntu รุ่นปัจจุบันทั้งหมด
jarno

@jarno ฉันลบมันเพราะ Z9iT กำลังถามเกี่ยวกับคำสั่งเฉพาะไม่ใช่วิธีที่ปลอดภัยในการลบเมล็ดเก่า อาจที่ยังคงมีความเกี่ยวข้อง แต่ในความคิดเห็นไม่คำตอบ :) (เช่นคุณได้)
เซท
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.