ทำไม xargs ทำให้ apt-get ยกเลิก?


17

ฉันกำลังพยายามลบรายการแพคเกจจากไฟล์ ฉันใช้คำสั่งต่อไปนี้:

cat packages | xargs sudo apt-get remove

packagesไฟล์ของฉันมีรายการแพ็คเกจที่ฉันต้องการลบหรือไม่ ทุกอย่างดูเหมือนจะทำงานได้ แต่apt-getยกเลิกแทนที่จะให้ฉันเลือกใช่หรือไม่

ฉันรู้ว่าฉันสามารถหลีกเลี่ยงสิ่งนี้ได้ด้วย-yตัวเลือก แต่ฉันอยากจะรู้ว่าทำไมสิ่งนี้จึงเกิดขึ้นและฉันจะเลือกตัวเลือกแบบโต้ตอบได้อย่างไร


มันทำงานอย่างไรดีเมื่อมันดูเหมือนว่ามันไม่ทำงานเลย? รายการในไฟล์ของคุณมีลักษณะอย่างไร คุณเคยลองsudo xargs --arg-file packages apt-get removeไหม
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

มันเป็น "งาน" เพราะ apt-get มาถึงจุดที่จะลบแพ็คเกจที่เหมาะสม ที่กล่าวว่า - ไฟล์argเป็นสิ่งที่ฉันกำลังมองหา คุณสามารถใส่คำตอบนั้นแล้วฉันจะยอมรับมัน ขอบคุณ!
ย่อย

คำตอบ:


13
xargs -a packages sudo apt-get remove

จะนำxargsไปอ่านข้อโต้แย้งโดยตรงจากpackagesนั้นจะปล่อยให้ stdin ไม่ถูกรบกวน


10

วิธีแก้ปัญหาทั่วไปที่มากกว่านั้นก็คือ

 sudo apt-get remove `cat packages`

ที่ที่คุณจะมีปัญหาหากรายการของแพ็คเกจยาวมาก

เหตุผลที่จะไม่ทำงานคือว่า apt-get พยายามที่จะอ่านการยืนยันของคุณจากอินพุตมาตรฐาน - เนื่องจากท่อ - catอยู่ติดกับ ตรงกันข้ามsudoสิ่งที่ถูกต้องโดยขอรหัสผ่านของคุณโดยการเปิด / dev / tty โดยตรง ฉลาดควรทำสิ่งนี้ แต่ดูเหมือนจะไม่


อินพุตมาตรฐานของ xargs เชื่อมต่อกับไพพ์จากcatแต่กระบวนการเริ่มต้นโดย xargs มีอินพุตมาตรฐานที่มาจาก / dev / null นี่คือพฤติกรรมของ xargs การสาธิตอย่างง่าย:echo "" | xargs ls -l /dev/self/fd
Juliano

1
@mws: ไม่มีไม่ควรเปิดapt-get มิฉะนั้นคุณจะไม่สามารถทำสิ่งที่ชอบ/dev/tty yes | apt-getรหัสผ่านนั้นสวยมากกรณีเดียวที่การอ่านจาก/dev/ttyเป็นสิ่งที่ถูกต้องและยังเป็นที่ถกเถียงกันมาก
Gilles 'หยุดความชั่วร้าย'

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

ฉันเห็น. มีความแตกต่างระหว่างนี้และ xargs -a ชื่อไฟล์เช่นแนะนำให้ ephemient หรือไม่?
sub

ใช่แล้วการใช้--arg-fileตัวเลือกephimemient นั้นดียิ่งขึ้นสำหรับกรณีเฉพาะซึ่งเป็นสาเหตุที่ฉัน upvoted สำหรับคำสั่งมากมายที่ไม่มีตัวเลือกนั้นคำอุปมา backtick-cat ยังคงมีการใช้งานอยู่
msw

2

เนื่องจากapt-getกำลังลบมากกว่าหนึ่งแพ็คเกจดังนั้นจึงต้องยืนยันการดำเนินการ ตั้งแต่มันอ่านจากท่อและไม่ได้เชื่อมต่อกับขั้วมันถือว่าอัตโนมัติSTDINNo

วิธีการรับรอบนี้ก็คือการเพิ่มการAPT::Get::Assume-Yesapt.conf


2

เห็นได้ชัดว่า xargs เปลี่ยนเส้นทาง STDIN ซึ่งสร้างความสับสนให้กับ apt-get เพื่อสมมติว่ามันกำลังทำงานในโหมดที่ไม่โต้ตอบ

ฉันอาจจะใช้สิ่งที่ชอบ

sudo apt-get remove $(cat packages)

เพื่อหลีกเลี่ยงการใช้ xargs เลย

("--arg-file" ไม่ได้อยู่ใน apt-get (8) คนหรือในคำศัพท์ที่ใช้งานของฉัน)


1

เพื่อหลีกเลี่ยง

ด้วย GNU xargs และ ksh / zsh / bash:

sudo xargs -r --arg-file <(cat packages) apt-get remove

(แน่นอนถ้าคำสั่งเป็นเพียงcatแล้วคุณสามารถแทนที่ด้วย<(cat packages)packages

หรือ:

< packages sudo xargs sh -c 'exec apt-get remove "$@" < /dev/tty' sh

ทั้งนี้ขึ้นอยู่กับรูปแบบของแฟ้ม "แพคเกจ" (การ xargs คาดว่ารายการที่ว่างเปล่าที่คั่นของการขัดแย้งและกระบวนการคำพูด ( ", 'และ\) ในขณะที่$(...)ไม่ได้คำพูดกระบวนการและการขยาย globbing รูปแบบ) คุณยังสามารถทำ:

sudo apt-get remove $(cat packages)

แต่โปรดทราบว่าระบบปฏิบัติการหลายระบบมีข้อ จำกัด เกี่ยวกับความยาวของบรรทัดคำสั่งดังนั้นจึงอาจไม่ทำงานหากรายการมีขนาดใหญ่ (ขณะที่xargsจะแก้ไขปัญหาด้วยการเรียกใช้หลายapt-getคำสั่ง)


0

ฉันอาจจะผิด แต่คุณสามารถลองและดูว่ามันใช้งานได้:

yes | sudo apt-get remove $(cat packages)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.