เพราะเหตุใดจึงไม่ได้มีการส่งข้อมูลนโยบายที่ฉลาด - แคช


12

ไม่เข้าใจสาเหตุ

$ apt-cache policy foo
N: Unable to locate package foo

แต่

$ apt-cache policy foo 2>&1 | grep .

มันว่างเปล่า.

ฉันกำลังทำข้อสันนิษฐานผิด

งานเดิม: ฉันต้องประมวลapt-cache policyผลเอาท์พุทน่าจะเป็น :-)

UPD :

fooใช้ในตัวอย่างของฉันอาจถูกแทนที่ด้วยชื่อแพคเกจใด ๆ ที่ไม่มีอยู่ในapt-getดัชนีของคุณ

UPD 2 :

มีคำตอบสำหรับวิธีแก้ปัญหา +50เงินรางวัลเพิ่มเติมจะมอบให้กับทุกคนที่อธิบายว่าทำไม2>&1โซลูชันไม่ทำงาน


# apt-cache policy vim 2>&1 |grep . vim: Installed: 2:7.4.712-2 Candidate: 2:7.4.712-2 Version table: *** 2:7.4.712-2 0 500 http://ftp.debian.org/debian/ sid/main amd64 Packages 100 /var/lib/dpkg/status
PersianGulf

1
@MohsenPahlevanzadeh ถูกต้องตอนนี้ลองโทรแน่นอน (ชื่อแพคเกจ) ฉันให้ :-)
zerkms

3
@MohsenPahlevanzadeh เหรอ? ฉันขอโทษ แต่คุณแน่ใจหรือว่าคุณได้อ่านคำถาม (และชื่อเรื่อง)?
zerkms

2
@MohsenPahlevanzadeh ไม่เท่ากับ (ไม่ปิด)
zerkms

1
ฉันเรียกใช้strace apt-cache policy foo 2>&1และมีการโทรของระบบioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0ฉันคิดว่าเนื่องจากการโทรนี้ 1 (stdout) มีปัญหา ฉันหมายความว่ามันไม่ได้เขียนเพื่อ TTY อีกต่อไป
esref

คำตอบ:


11

หาก stdout ไม่ใช่ tty (เช่นเป็นไฟล์ปกติหรือไพพ์) และหากไม่มี--quietการระบุตัวเลือกไว้apt-cacheจะทำหน้าที่เหมือนกับว่าคุณผ่านมันไป--quiet=1แล้ว วิธีแก้ปัญหาคือการส่ง--quiet=0ตัวเลือก

$ apt-cache --quiet=0 policy foo 2>&1 | grep .
N: Unable to locate package foo


10

ดูเหมือนจะมีบางพฤติกรรม cheaty apt-cacheสำหรับการเปลี่ยนเส้นทางใน แต่เราสามารถโกงคนโกงโดยการสลับ stdout และ stderr !

ลองอันนี้มันควรจะได้ผล:

apt-cache policy foo 3>&1 1>&2 2>&3 3>&- | grep .

7

หากคุณเรียกใช้strace apt-cache policy foo 2>&1คำสั่งคุณจะเห็นบรรทัดioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

เนื่องจากคำสั่งนั้นจัดการ 1 (stdout) ดังนั้น 1 จึงไม่ถูกเขียนไปยัง stdout อีกต่อไป และถ้าคุณเปลี่ยนเส้นทาง 2 เป็น 1 คุณจะสูญเสียทั้งสองอย่าง

แก้ไข: นี่คือตัวอย่างโค้ดจาก apt-cache source code:

// Deal with stdout not being a tty
   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
      _config->Set("quiet","1");

ตกลง. มีวิธีใดที่จะจับมันได้หรือไม่
zerkms

1
ฉันไม่พบวิธีอื่นใดนอกจากคำตอบของ @ Mr_Mig (Mine เป็นapt-cache policy foo 1>&2 2>&1 | grep .) แต่ฉันพบว่าในซอร์สโค้ด apt apt-cache :) // จัดการกับ stdout ไม่ใช่ tty if (! isatty (STDOUT_FILENO) && _config-> FindI ("เงียบ", -1) == - 1) _config-> Set ("เงียบ", "1");
Esref

Btw ฉันยังเป็นแฉกโดยคนไปยังจุดเดียวกันในแหล่งที่มาเพียงไม่กี่นาทีที่ผ่านมา :-) และวิธีการแก้ปัญหาที่อาจเกิดขึ้นได้ดีขึ้นscript -c "sudo apt-cache policy foo" | grep Unableซึ่งจะต้องมีการติดตั้งscriptแม้ว่า ตามคำแนะนำ - ฉันจะใส่ +50 ที่นี่ใน 2 วัน (SE ไม่อนุญาตให้ทำก่อนหน้านี้)
zerkms

2
@Esref ความคิดเห็นของคุณเกี่ยวกับ "ฉันพบว่าในซอร์สโค้ด apt apt-cache ... " ควรอยู่ในคำตอบดังนั้นโปรดเพิ่มไปที่นั่น +1 :
Faheem Mitha

โอ้พระเจ้าไม่มีตัวเลือกค่าหัว +50 อีกต่อไป :-(
zerkms

3

ทางออกที่ "ดีกว่า" คือการใช้scriptยูทิลิตี:

script -c "apt-cache policy foo" /dev/null | grep .

stdoutวิธีการที่จะขัดขวางการส่งออกทั้งหมดและส่งต่อไปยัง

ข้อเสียเปรียบเพียงอย่างเดียวคือคุณต้องติดตั้งscriptหากคุณยังไม่มี ใน ubunty มันให้บริการโดยbsdutilsแพคเกจ

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