การทุบตีเสร็จสิ้นทำให้การทุบตีเริ่มต้นช้าลง


15

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

ความคิดใด ๆ ที่ฉันสามารถค้นหาว่าปัญหาคืออะไรหรือฉันจะเร่งความเร็วในสิ่งต่าง ๆ ได้อย่างไร


นี่ / bin / bash คืออะไร? - ลอง / bin / dash อาจเร็วขึ้นสักหน่อย
Sirex

3
นี่คือเหตุผลที่ฉันยกเลิกการติดตั้ง bash-completion
Vi

คำตอบ:


8

อัปเดตในปี 2013: การทำ bash-เสร็จสิ้นส่วนใหญ่ถูกเขียนใหม่เพื่อความสมบูรณ์อัตโนมัติเมื่อจำเป็นเท่านั้น ตอนนี้สคริปต์หลักน้อยกว่ามาก


สคริปต์ที่เสร็จสมบูรณ์อาจมีขนาดใหญ่มากในมาตรฐานเชลล์สคริปต์ หนึ่งในเซิร์ฟเวอร์ของฉันมีการเข้าถึงก็เกือบ 1,700 เส้น (57 KB) และนั่นเป็นเพียงสคริปต์หลัก ใน/etc/bash_completion.dมี ~ 200 สคริปต์อื่น ๆ เพิ่มเติมสำหรับคำสั่งอื่น ๆ ( openssl, mutt, mount... ) รวมเป็นเงินทั้งสิ้น 25,537 เส้นหรือ 1.2 MB แต่ละสคริปต์จะตรวจสอบว่ามีคำสั่งจริงหรือไม่ก่อนที่จะกำหนดตัวจัดการความสมบูรณ์ ในกรณีนี้จะมีประมาณ 330 ครั้งซึ่งแต่ละไฟล์จะเกี่ยวข้องกับการตรวจสอบ$PATHไฟล์ที่ปฏิบัติการได้ด้วยชื่อที่กำหนด (แม้ว่าฉันคาดว่า/usr/binจะถูกเก็บไว้ในหน่วยความจำ ... )

ยอมรับแม้กระทั่งว่าจะใช้เวลาเพียงครึ่งปีที่สองในการโหลดไม่เต็มสองวินาที แต่มันอาจเป็นส่วนหนึ่งของปัญหา เรียกใช้du -hs /etc/bash_completion*หรือwc -l /etc/bash_completion{,.d/*} | grep totalถ้าคุณต้องการตรวจสอบ


คุณสามารถลองจัดหาสคริปต์ด้วยตนเองในโหมด "ติดตาม":

set -x
. /etc/bash_completion

คุณจะเห็นแต่ละบรรทัดขณะดำเนินการ หากมีคำสั่งเฉพาะที่ใช้เวลานานคุณควรสังเกต

( set +xปิดใช้งานโหมดติดตาม)


คุณสมบัติคืบแม้ในโหมดข้อความแบบง่าย ๆ ? มีโอกาสมากกว่าที่คุณคิด
วิ

@Vi: หลังจากเห็น zsh รวบรวมสคริปต์เริ่มต้นของมันเป็น bytecode ...
user1686

1
ขอขอบคุณ. นั่นเป็นเรื่องง่ายจริงๆ น่าเสียดายที่คำสั่งทั้งหมดไม่แตกต่างกัน ดังนั้นมันจึงดูเหมือนว่าเป็นจำนวนมหาศาลที่ทำให้เกิดปัญหา
user75250

12

ฉันพบโซลูชันแฮ็คบิตที่ดูเหมือนว่าจะทำงานได้ดีพอสมควร

วิธีการแก้

ที่ด้านล่างของการ~/.bashrcเพิ่ม:

กับดัก 'source / etc / bash_completion; กับดัก USR1 'USR1
{นอน 0.1; builtin kill -USR1 $$; } & ปฏิเสธ

คำอธิบาย

trap 'source /etc/bash_completion ; trap USR1' USR1

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

{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

รอสักครู่แล้วส่งสัญญาณไปยังเชลล์ปัจจุบัน disownจำเป็นต้องระงับbashการป้อนกลับการควบคุมกระบวนการ sleepจำเป็นสำหรับการทำงานแบบอะซิงโครนัส

ปัญหาที่เกิดขึ้น

ด้วยเหตุผลบางอย่างคำสั่งแรกที่ออกให้กับเชลล์นี้จะไม่ถูกบันทึกในประวัติ


1
สิ่งนี้ดูเหมือนจะไม่เพิ่มการเริ่มต้น - time bash -lc trueรายงาน ~ 0.12 วินาทีที่มีหรือไม่มีสิ่งนี้แม้ว่าtime source /etc/bash_completionรายงานตัวเลขที่สูงกว่าเช่น 0.26s สิ่งนี้ได้รับการแก้ไขอย่างมีประสิทธิภาพหรือไม่
l0b0

ฉันไม่ทราบว่าtime bash -lc trueทำงานได้อย่างถูกต้องที่นี่ตั้งแต่trueเสร็จสิ้นมาก่อน~0.1sหรือไม่ อย่างไรก็ตามtime source /etc/bash_completionรายงานประมาณ 0.17 วินาทีที่นี่และนั่นเป็นเวลาที่ฉันต้องรอให้PS1ปรากฏ
cYrus

2
แยบยล! ในคำอธิบายคำสั่ง trap จะหายไปUSR1เมื่อสิ้นสุด
Fish Monitor

ด้วย SIGUSR ตัวจัดการสัญญาณจะไม่ถูกเรียกใช้จนกระทั่งหลังจากฉันกด enter ที่พร้อมต์เชลล์ มีการหยุดที่จุดนั้นในขณะที่มันทำงานอยู่ ฉันเปลี่ยนมาใช้ SIGQUIT และทำงานได้ดี
Jon Nalley

5

คุณควรใช้ bash_completion เวอร์ชันล่าสุด (2.0) หากคุณใช้ Debian อยู่มันเป็นเสียงดังฮืด ๆ แต่มันไม่มีการอ้างอิงกับแพ็คเกจเสียงหวีดอื่น ๆ ดังนั้นคุณสามารถติดตั้งลงบนบีบได้โดยไม่มีปัญหา

รุ่นล่าสุดโหลดเสร็จสมบูรณ์แบบไดนามิกได้ทันทีดังนั้นมันจึงแบ่งเวลาโหลดที่พร้อมท์ให้ฉันอย่างน้อย 10 เท่า


1

คุณสามารถใช้ตัวยึดตำแหน่งในขณะที่กำลังโหลดความสำเร็จ มันควรจะเพียงพอที่จะหลอกตาของคุณ เห็นได้ชัดว่าทำงานได้ก็ต่อเมื่อเวลาที่ต้องการsource /etc/bash_completionน้อยกว่าเวลาที่คุณต้องการพิมพ์และออกคำสั่งเชลล์แรกมิฉะนั้นจะล่าช้าเช่นกัน

ความคิดคือการสะท้อนของปลอมPS1แหล่งที่มาของความสำเร็จและในที่สุดก็กลายเป็นเทอร์มินัล

สมมติว่าคุณPS1เป็น\u@\h:\w\$พวกเขาคุณอาจจะเขียนสิ่งที่ชอบ:

echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'

ที่ไหน:

  • 2J ลบเทอร์มินัล
  • H เลื่อนเคอร์เซอร์ไปที่มุมขวาบน

หมายเหตุ:คุณอาจต้องการตรวจสอบว่าผู้ใช้เป็นรูทและใช้#แทน$เพื่อความมั่นคงหรือไม่:

echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "

หมายเหตุ:การลบ\e[2Jเพื่อหลีกเลี่ยงการกะพริบ แต่จะทิ้งอักขระขยะไว้หากตัวยึดยาวกว่าพรอมต์ที่เกิดขึ้นจริง

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