บังคับให้นามแฝงที่ 'เพิ่ม' ให้กับทุกคำสั่ง


11

เป็นไปได้ไหมที่จะบังคับให้เพิ่มชื่อแทนเวลา (เนื่องจากไม่มีวิธีที่ดีกว่าในการเขียนวลี) ให้กับทุกคำสั่งbash?

ตัวอย่างเช่นผมต้องการที่จะมีผู้ใช้เฉพาะที่เมื่อใดก็ตามที่คำสั่งจะดำเนินการก็จะห่อเสมอทั้งที่มีก่อนและหลังหรือdatetime

เป็นไปได้และถ้าเป็นเช่นนั้นได้อย่างไร


ฉันดูมาก่อนและไม่สามารถหาวิธีที่จะทำสิ่งนี้ได้ ดังที่ Caleb กล่าวคุณสามารถใช้preexecแต่คุณไม่ต้องการเรียกใช้ภายในpreexec(เช่นpreexec() { time $1; }) เนื่องจากเชลล์ยังคงรันหลังจากpreexecส่งคืน ดังนั้นสิ่งที่ดีที่สุดที่เราสามารถทำได้คือสิ่งที่คล้ายกัน
มิเคล

@Mikel ฉันคิดว่าคุณสามารถใช้preexec()ฟังก์ชั่นเพื่อห่อหุ้มสิ่งที่กำลังดำเนินการโดยดึงคำสั่งเรียกใช้ด้วยตัวคุณเองจากภายในฟังก์ชั่นแล้วส่งกลับข้อผิดพลาดบางอย่างเพื่อให้เปลือกไม่ได้ไปดำเนินการคำสั่งเอง
Caleb

คำตอบ:


10

คุณสามารถบันทึกเวลาที่บรรทัดคำสั่งเริ่มทำงานและเวลาที่แสดงพร้อมต์ Bash ติดตามวันที่เริ่มต้นของแต่ละบรรทัดคำสั่งในประวัติเรียบร้อยแล้วและคุณสามารถบันทึกเวลาเมื่อคุณแสดงพรอมต์ถัดไป

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

นี่ให้ความละเอียดที่สองเท่านั้นและเฉพาะเวลานาฬิกาแขวน หากคุณต้องการความละเอียดที่ดีกว่าคุณต้องใช้dateคำสั่งภายนอกที่รองรับ%NรูปแบบของนาโนวินาทีและDEBUGกับดักเพื่อโทรdateก่อนใช้คำสั่งเป็นครั้งคราว

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

แม้กับกับDEBUGดักฉันไม่คิดว่าจะมีวิธีการแสดงเวลาประมวลผลโดยอัตโนมัติสำหรับแต่ละคำสั่งหรือแยกแยะมากกว่าการแจ้งให้พรอมต์


หากคุณยินดีที่จะใช้เชลล์ที่แตกต่างกันต่อไปนี้เป็นวิธีการรับรายงานเวลาสำหรับทุกคำสั่งใน zsh (นี่ไม่ได้พูดคุยกับงานอื่น ๆ ):

REPORTTIME=0

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

zsh เอาคุณลักษณะนี้จาก csh timeที่ตัวแปรที่เรียกว่า


3

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

โดยการสร้างฟังก์ชั่นคู่นี้คุณสามารถมีคำสั่งโดยพลการใด ๆ ที่คุณต้องการเรียกใช้ก่อนและหลังคำสั่งใดก็ตามที่ออกพร้อมท์ คุณสามารถใช้สิ่งนี้เพื่อบันทึกการใช้เชลล์สร้างล็อคทดสอบสภาพแวดล้อมหรือในตัวอย่างของคุณคำนวณเวลาหรือทรัพยากรที่ใช้ในขณะที่คำสั่งทำงาน

ในตัวอย่างนี้เราจะสร้างตัวประทับเวลามาตรฐานก่อนที่จะเรียกใช้คำสั่งโดยใช้preexec()จากนั้นคำนวณเวลาที่ใช้ในการดำเนินการคำสั่งโดยใช้precmd()และส่งออกคำสั่งก่อนที่จะให้พรอมต์หรือออกจากระบบ ตัวอย่าง:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

หมายเหตุ:สำหรับตัวอย่างนี้มีฟังก์ชั่นบิวด์อินที่ง่ายยิ่งขึ้น สิ่งที่คุณต้องทำคือเปิดการรายงานรันไทม์ใน ZSH และจะทำสิ่งนี้โดยอัตโนมัติ

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

ในการใช้งานจริงpreexec()ฉันใช้มันดูว่าเชลล์กำลังทำงานอยู่ภายในtmuxหรือไม่screenและถ้าเป็นเช่นนั้นเพื่อส่งข้อมูลเกี่ยวกับคำสั่งต้นน้ำที่กำลังทำงานอยู่เพื่อแสดงในแท็บชื่อ

น่าเสียดายที่การทุบตีกลไกเล็ก ๆ นี้ไม่มีอยู่จริง นี่คือชายคนหนึ่งพยายามที่จะทำซ้ำ ดูคำตอบของ Gillesสำหรับแฮ็คเล็ก ๆ ที่คล้ายกัน


1
และนี่เป็นรุ่นที่เรียบง่ายของเคล็ดลับ precmd ผ่าน DEBUG
Gilles 'หยุดชั่วร้าย'

ดูเพิ่มเติมที่unix.stackexchange.com/questions/8607/…
มิเคล

หวังว่านี้มีอยู่ในทุบตี!
วอร์เรน

ดูลิงก์ของGillesและอื่น ๆ มันสามารถนำไปใช้ในการทุบตีด้วยการเล่นซอเล็กน้อย อีกครั้งทำไมคุณไม่เรียกใช้ zsh มันเป็นเปลือกโยกที่มีเหตุผลที่ดีกว่าที่จะเปลี่ยนมากกว่านี้!
Caleb

2
หากคุณใช้ zsh มีวิธีที่ดีกว่าในการทำเช่นนั้น ตัวแปรสภาพแวดล้อม REPORTTIME เมื่อตั้งค่าจะส่งออกข้อมูลเวลาดำเนินการ (ราวกับว่าคุณใช้คำสั่งด้วย 'เวลา' อยู่ข้างหน้า) สำหรับคำสั่งใด ๆ ที่ใช้เวลานานกว่า $ REPORTTIME วินาที เพียงแค่ตั้งค่าเป็น 0 และมันควรจะบอกคุณเวลาสำหรับทุกคำสั่งด้วยการสลายตัวของผู้ใช้ / sys ในการบูต
โจเซฟ Garvin

1

PROMPT_COMMANDวิธีที่ง่ายที่สุดอาจจะไปยังชุด ดูตัวแปร Bash :

PROMPT_COMMAND
หากตั้งไว้ค่าจะถูกตีความเป็นคำสั่งเพื่อดำเนินการก่อนการพิมพ์ของแต่ละพรอมต์หลัก ( $PS1)

ตัวอย่างเช่นเพื่อหลีกเลี่ยงการเขียนทับคำสั่งที่มีอยู่ใด ๆ ที่มีอยู่คุณสามารถทำได้:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

ไม่ทราบเกี่ยวกับสิ่งนั้น - ดูเหมือนเป็นการเริ่มต้นที่ดี @cjm
warren

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

0

csh/ tcshมีการสนับสนุนที่ดีที่สุดสำหรับคุณลักษณะนี้ (และมีอยู่เสมอ)

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

ในคำอื่น ๆ set time=1จะพิมพ์เวลาที่ใช้ (ระบบผู้ใช้ผ่านไป) โดยคำสั่งใด ๆ ที่ใช้เวลามากกว่า 1 วินาทีของเวลา cpu ธรรมดาset timeจะเปิดใช้งานการพิมพ์เวลาสำหรับคำสั่งทั้งหมด

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