apt-get remove พร้อมวิธีลบ wildcard มากกว่าที่คาดไว้ ทำไม?


38

เมื่อคืนฉันพยายามเผาซีดี ถูกรำคาญด้วย k3b และเลือกที่จะใช้ brasero แทนฉันไปลบ k3b

ฉันพิมพ์ใน:

sudo apt-get remove k3b

ฉันกดแท็บสองครั้งและเห็นว่าฉันมีทั้งข้อมูล k3b และ k3b บนระบบของฉัน สมมติว่าฉันไม่ต้องการข้อมูล k3b บนระบบของฉันหากไม่มี k3b ฉันต้องการลบมันด้วยดังนั้นฉันจึงพิมพ์ใน:

sudo apt-get remove k3b*

น่าเสียดายที่ฉันกด Y เพื่อยืนยันโดยไม่ได้ดู มันถอนการติดตั้งมากทั้งมากกว่าและk3b k3b-dataมันถอนการติดตั้งแพคเกจที่ไม่เหมาะสมกับk3b*regex ของฉัน ตัวอย่างเช่น: และtransmissionnetwork-manager

ฉันค่อนข้างแน่ใจว่าฉันไม่ได้มีช่องว่างระหว่างk3bและ*แต่ฉันไม่รู้ว่าทำไมมันจะลบทั้งหมดที่มันทำ มีบางอย่างเกี่ยวกับ apt-get หรือไม่ที่ฉันเข้าใจผิด?


คำตอบ:


38

คำสั่งที่คุณต้องการคือsudo apt-get remove '^k3b.*'เพราะ:

  • คุณต้อง.*ตรงกับตัวละครใด ๆ จำนวนครั้งใด ๆ
  • คุณต้อง^ตรงกับจุดเริ่มต้นของสตริง
  • คุณต้องอ้างถึง regex เพื่อป้องกันการทุบตีจากการตีความ*เป็นสัญลักษณ์แทน

(คำตอบนี้เสร็จสมบูรณ์และสรุปข้อมูลก่อนหน้านี้โดย qbi และ Flimm)


5
นี้มีความปลอดภัยและมันโอเคที่จะใช้มัน .*แต่คุณไม่จำเป็นต้อง sudo apt-get remove ^k3bคุณก็สามารถใช้ การมีอยู่ของ^เพียงพอที่จะทำให้อาร์กิวเมนต์ถูกตีความว่าเป็นนิพจน์ทั่วไปและเมื่อaptหรือapt-getตีความอาร์กิวเมนต์เป็นนิพจน์ทั่วไปมันจะจับคู่กับมันในที่ใดก็ได้ในชื่อแพ็คเกจ นั่นเป็นเหตุผลที่คุณต้องการ^- เพื่อยึดการจับคู่กับจุดเริ่มต้นของชื่อแพคเกจ การแสดงออกปกติไม่จำเป็นต้องตรงกับชื่อแพคเกจทั้งหมดเพียงส่วนใดส่วนหนึ่งของมัน
Eliah Kagan

1
@EliahKagan ขอบคุณสำหรับข้อมูลเพิ่มเติม! (และแน่นอนมันทำให้รู้สึกว่าถ้าคุณต้องการ^แล้วคุณไม่จำเป็นต้องใช้.*)
Boris Dalstein

30

การแสดงออกปกติ*หมายถึงศูนย์หรือหลายคนโดยพลการ ดังนั้นคุณบอกว่าapt-getจะเอาอะไรที่มี k3ตามด้วยหมายเลขใด ๆดังนั้นโดยทั่วไปทุกอย่างที่มีb k3หากฉันลองคำสั่งของคุณในระบบของฉันมันต้องการที่จะลบ 58 แพคเกจ

sudo apt-get remove -s k3b*
Package k3b is not installed, so not removed
Package k3b-data is not installed, so not removed
Package k3b-dbg is not installed, so not removed
Package libcanberra-gtk3-0 is not installed, so not removed
Package libcanberra-gtk3-0-dbg is not installed, so not removed
Package libcanberra-gtk3-dev is not installed, so not removed
…
The following packages will be REMOVED:
  appmenu-gtk ardour audacity brasero brasero-cdrkit firefox-globalmenu
  gconf-editor gir1.2-appindicator-0.1 gnome-applets gnome-control-center
…
0 upgraded, 2 newly installed, 58 to remove and 0 not upgraded.

ฮึ! ฉันติดการทำงานกับเครื่อง windows darn เหล่านี้ (ซึ่ง * หมายถึง "และอะไรก็ตามหลังจาก") นานเกินไป!
Steve Goykovich

14
การ*ทำงานเป็น wildcard สำหรับทุบตีเช่นใน DOS แต่คำสั่งบางอย่างเช่นapt-getคาดว่า regex เมื่อคุณพิมพ์sudo apt-get remove -s k3b*ทุบตีแรกจะมองหาไฟล์ใด ๆ k3bในไดเรกทอรีปัจจุบันของคุณที่ขึ้นต้นด้วย หากพบสิ่งใด ๆ มันจะแทนที่อาร์กิวเมนต์ด้วยชื่อไฟล์เหล่านั้น ถ้าไม่มันจะส่งk3b*ตรงไปยังapt-getซึ่งจะตีความว่าเป็น regex หากคุณไม่ต้องการทุบตีเพื่อตีความเครื่องหมายดอกจันเป็นสัญลักษณ์แทนก่อน (ซึ่งคุณอาจไม่ต้องการ) ให้ล้อมอาร์กิวเมนต์ด้วยเครื่องหมายคำพูดเดี่ยวเช่นนี้:sudo apt-get remove -s 'k3b*'
Flimm

3
sudo apt-get remove -s 'k3b.*'ดังนั้นคำสั่งที่ตั้งใจไว้จะได้รับ เพิ่งสะดุดเมื่อคำตอบนี้และพบว่ามันสำคัญที่ต้องรู้ IMHO สิ่งนี้ค่อนข้างคาดไม่ถึงและฉันค่อนข้างจะทำเครื่องหมายว่าเป็น "พฤติกรรมที่ไม่คาดคิด" ของ apt-get ... โดยปกติคุณคาดหวังความหมาย "glob" และไม่ใช่ "regexp" ความหมายหากไม่ได้ระบุไว้ ขอบคุณและ +1!
Rmano

1
และสำหรับคนอย่างฉันที่ไม่รู้: -sตัวเลือกหมายถึง "การจำลอง" มันบอกว่าจะapt-getไม่ทำการดำเนินการ แต่เพียงเพื่อแจ้งให้คุณทราบสิ่งที่จะเกิดขึ้นโดยไม่มี-sตัวเลือก
Boris Dalstein

ฉันคิดว่าการใช้คำพูดเดี่ยวของคุณเพื่อสร้างความกลมกลืนไม่ได้ผลอย่างน้อยในหุ่นเชิด และนั่น เป็นสิ่งที่คาดไม่ถึง ในโปรแกรม 'find' ถ้าฉันเขียน find / -iname 'project *' ฉันจะพบทุกสิ่งที่ขึ้นต้นด้วย project ไม่ใช่สิ่งที่มี 'project' อยู่ในนั้นและทุกอย่างที่อยู่หลังมัน เป็นข้อพิสูจน์เกี่ยวกับหุ่นกระบอกสังเกตว่าผลลัพธ์ของฉันพูดว่า 'regex' และผลลัพธ์นั้นพิสูจน์ได้อย่างไร
Dennis

9

ใช้sudo apt-get remove ^k3bแทน เมื่อคุณติดตั้งหรือลบแพ็คเกจ*มักเป็นอันตรายและไม่จำเป็น ถ้าคุณทำเช่นการใช้งาน*คุณควรพูด แต่นั่นก็ไม่ได้ทำให้มันปลอดภัยมากขึ้นเพราะแนวโน้มที่จะเลือกแพคเกจที่ไกลมากขึ้นกว่าที่คุณตั้งใจที่เป็นผลมาจากวิธีการaptและการapt-getแปลความหมายของมันและไม่ได้ผลของการขยายตัวของพา

  • แม้การใช้งานความปลอดภัยของการ*เป็นมักจะไม่จำเป็น
  • การใช้งานที่ไม่ปลอดภัยจะโหดร้าย การk3b*ลบจะลบทุกแพ็คเกจที่มีk3 ที่ใดก็ได้ในชื่อ (และทุกแพ็คเกจที่ขึ้นอยู่กับแพ็คเกจดังกล่าว) นั่นไม่ใช่การพิมพ์ผิดที่k3เพียงพอแม้จะไม่มีbเพราะb*หมายถึง "ศูนย์หรือมากกว่าbนั้น"

เมื่อคุณเรียกใช้aptหรือapt-getกับinstall, removeหรือpurgeการกระทำแต่ละอาร์กิวเมนต์ที่ตามมาเป็นครั้งแรก1ตีความว่าเป็นชื่อของแพคเกจของแต่ละบุคคล หากมีแพ็คเกจที่มีชื่อที่แน่นอนนั้นจะมีการดำเนินการให้

ถ้าไม่มีแพคเกจดังกล่าวaptและapt-getจะตรวจสอบว่ามีการโต้แย้งใด ๆ ที่พบการแสดงออกปกติ metacharacters 2 . , ?, +,* , |, \[, หรือ^ $ถ้าไม่ทำก็เสร็จ - ไม่พบแพ็คเกจ

ถ้ามันไม่มีการใด ๆ ของตัวละครเหล่านั้นแล้วก็จะถือว่าเป็นนิพจน์ปกติและจับคู่กับส่วนใดส่วนหนึ่งของชื่อแพคเกจใด ๆ ไม่จำเป็นต้องตรงกับชื่อทั้งหมด อย่างที่คนอื่น ๆ พูดกัน*ในการแสดงออกปกติไม่ได้มีความหมายเหมือนกับ*ในกลม ?ไม่เหมือนกัน ในการแสดงออกปกติ:

  • *อนุญาตให้รายการก่อนหน้าปรากฏจำนวนครั้งใดก็ได้รวมถึงเพียงครั้งเดียวหรือไม่เลยแทนที่จะเป็นครั้งเดียว
  • ?ทำให้รายการก่อนหน้านี้เป็นตัวเลือก -นั่นคืออนุญาตให้ปรากฏเป็นศูนย์หรือหนึ่งครั้ง

apt-get (8) ( man apt-get) พูดว่า:

หากไม่มีแพ็คเกจที่ตรงกับนิพจน์ที่กำหนดและนิพจน์มีหนึ่งใน '.', '?' หรือ '*' จากนั้นจะถือว่าเป็นนิพจน์ปกติ POSIX และใช้กับชื่อแพ็กเกจทั้งหมดในฐานข้อมูล การแข่งขันใด ๆ ที่ติดตั้งแล้ว (หรือลบ) โปรดทราบว่าการจับคู่จะกระทำโดยสตริงย่อยดังนั้น 'lo. *' จะจับคู่ 'How-Lo' และ 'ต่ำสุด' หากสิ่งนี้ไม่พึงประสงค์ให้สมอนิพจน์ทั่วไปด้วยอักขระ '^' หรือ '$' หรือสร้างนิพจน์ทั่วไปที่เฉพาะเจาะจงมากขึ้น

manpage เพียงกล่าวถึง., ?และ*แต่มันเป็นเรื่องที่ไม่สมบูรณ์เช่น+, |, [, ^และ$นอกจากนี้ยังมีเพียงพอที่จะให้apt-getหรือaptตีความรูปแบบเช่นการแสดงออกปกติ 3

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

manpage กล่าวและ^ $เหล่านี้ (โดยเฉพาะ^) เป็นกุญแจสำคัญในการเขียนความปลอดภัยรูปแบบที่มีประสิทธิภาพสำหรับใช้กับinstall, removeหรือpurgeการดำเนินการในหรือaptapt-get

  • ^ยึดการแสดงออกปกติถึงจุดเริ่มต้นของสตริงทั้งหมด ^k3bเลือกแพ็กเกจทั้งหมดที่มีชื่อเริ่มต้นk3bด้วย
  • $โยงการแสดงออกปกติถึงจุดสิ้นสุดของสตริงทั้งหมด k3b$จะเลือกแพ็กเกจทั้งหมดที่มีรายชื่อท้ายk3bด้วย

ดังนั้นคุณสามารถใช้คำสั่งนี้เพื่อลบแพ็กเกจอย่างปลอดภัย:

sudo apt-get remove ^k3b

ในที่สุดในกรณีเฉพาะที่คุณพูดถึงคุณอาจส่งชื่อตัวเองทั้งสอง:

sudo apt-get remove k3b k3b-data

จากนั้นคุณหลีกเลี่ยงความซับซ้อนทั้งหมด! (แม้ว่าการยึดกับ^ทำได้ง่าย ๆ เมื่อคุณคุ้นเคย) หรือใช้การขยายรั้งซึ่งเชลล์ของคุณขยายเข้าไปในคำสั่งด้านบน:

sudo apt-get remove k3b{,-data}

1 มีสองข้อยกเว้นนี้: (ก)ตัวเลือกบางอย่าง (เช่น-f, --purge) ได้รับการยอมรับและ (ข)บางตัวอักษรวรรคตอนปรากฏที่ปลายของการโต้แย้งที่มิฉะนั้นจะนำมาเป็นชื่อแพคเกจในการดำเนินการสามารถใช้เป็น ใช้เพื่อแก้ไขสิ่งที่ทำ (เช่นsudo apt install ubuntu-desktop^ติดตั้งงานแทนแพ็คเกจและเมื่อ^ปรากฏที่ท้าย)

2 ตัวบ่งชี้การแสดงออกปกติอื่น ๆ ที่มีอยู่ ตัวอย่างเช่น\ได้รับการสนับสนุนโดยภาษาถิ่นทั้งหมดของการแสดงออกปกติและใช้กันทั่วไป ., ?, +, *, |, [, ^และ$เพียงแค่เกิดขึ้นจะ metacharacters ที่นักพัฒนา APT ตัดสินใจที่จะเรียกการตีความเป็นนิพจน์ปกติ (หลังความละเอียดเป็นแพคเกจที่แน่นอนชื่อล้มเหลว)

3 วิธีที่ง่ายที่สุดในการตรวจสอบสิ่งนี้คือการจำลองการติดตั้งหรือลบด้วยรูปแบบดังกล่าวโดยใช้-sตัวเลือกตามที่อธิบายไว้ข้างต้น ยกตัวอย่างเช่นการทำงานapt -s install ^virtualboxแสดงให้เห็นว่าจะมีผลกระทบต่อความพยายามที่จะติดตั้งแพคเกจแพคเกจผู้จัดการรู้เกี่ยวกับที่มีชื่อขึ้นต้นด้วยทุกคนsudo apt install ^virtualbox virtualboxอย่างไรก็ตามพฤติกรรมนี้ยังสามารถตรวจสอบได้โดยการตรวจสอบรหัสที่มา ตรวจสอบฟังก์ชั่นในCacheSetHelper::PackageFromRegExcacheset.cc


1

คุณน่าจะลบ lib ที่มี k3b อยู่ในนั้นซึ่งโปรแกรมเหล่านั้นขึ้นอยู่กับ

ในระยะสั้นคุณอาจไม่เคยรู้ ฉันไม่แนะนำให้ใช้ตัวแทนเพื่อลบสิ่งต่าง ๆ และอ่านสิ่งต่าง ๆ เมื่อได้รับแจ้ง (ขออภัย)

นอกจากนี้หากไม่มีการค้นหา -n regex ให้ใช้ฟิลด์ทั้งหมดไม่ใช่เฉพาะชื่อ

http://ccrma.stanford.edu/planetccrma/man/man8/apt-cache.8.html

qbi ยังถูกต้อง regex ของคุณมีข้อบกพร่องจากการเดินทาง


อีกอย่างหนึ่ง, ในกรณีเช่นคุณ (ข้อมูล k3b และ k3b) เพียงถอนการติดตั้ง k3b apt-get Apt จะแจ้งให้คุณทราบหากคุณมีสิ่งที่ติดตั้งซึ่งคุณไม่ต้องการอีกต่อไปและสิ่งที่คุณต้องทำเพื่อลบออก
coteyr

ว้าว! ฉันไม่เคยคาดหวังให้มันค้นหาคำอธิบายเช่นกัน! ใช่นี่เป็นสิ่งที่ฉันจะไม่ทำอีกแน่นอน! (และฉันจะแน่ใจว่าได้อ่านสิ่งต่าง ๆ ในครั้งต่อไป: P)
Steve Goykovich

ลิงก์ใช้งานไม่ได้คุณจะต้องชี้แจงวิธีใช้ -n หรือไม่
Seanny123

-n หมายถึงค้นหาเฉพาะในฟิลด์ชื่อ
coteyr

หลังจากที่พยายามที่ตัวเลือก n ไม่ได้รับการยอมรับโดยเฉพาะโดยapt-get remove apt-get cacheดูเหมือนว่าจริง ๆ แล้วค้นหาapt-get removeเฉพาะชื่อแพคเกจไม่ใช่คำอธิบาย
Boris Dalstein
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.