ฉันจะเปลี่ยนทิศทางผลลัพธ์ของคำสั่ง“ เวลา” ได้อย่างไร


96

ฉันพยายามเปลี่ยนทิศทางผลลัพธ์ของคำสั่งเวลา แต่ไม่สามารถ:

$time ls > filename
real    0m0.000s
user    0m0.000s
sys     0m0.000s

ในไฟล์ฉันเห็นผลลัพธ์ของlsคำสั่งไม่ใช่ของtime. โปรดอธิบายว่าทำไมฉันถึงทำไม่ได้และทำอย่างไร


1
ฉันคิดว่าควรจะเป็น Superuser
Mnementh

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

คำตอบ:


105

คุณสามารถเปลี่ยนเส้นทางเอาต์พุตเวลาโดยใช้

(time ls) &> file

เนื่องจากคุณต้องใช้ (time ls) เป็นคำสั่งเดียวจึงจะใช้วงเล็บปีกกาได้


1
ใช้ได้ดี แต่คำถามคือพวกเขาทำสิ่งนี้ได้อย่างไร?
abubacker

2
คำสั่ง time จะใช้อาร์กิวเมนต์เป็นคำสั่ง แต่วงเล็บจะจัดกลุ่มเป็นคำสั่งเดียว เช่น time ls> file1.txt ในอาร์กิวเมนต์ 0 = time 1 = "ls> file1.txt"
sganesh

9
และคำสั่ง time พิมพ์เอาต์พุตใน stderr ดังนั้นคุณสามารถใช้ (เวลา ls) 2> file
sganesh

5
คำชี้แจง&>เกี่ยวกับเรื่องนี้ฉันสามารถเรียนรู้เกี่ยวกับสิ่งเหล่านี้ได้ที่ไหน
hello_there_andy

3
@hello_there_andy &>fileคล้ายกับ>file 2>&1. มันกำกับทั้ง stdout และ stderr
ktbiz

132

ไม่จำเป็นต้องเปิดเชลล์ย่อย ใช้บล็อกรหัสจะทำเช่นกัน

{ time ls; } 2> out.txt

หรือ

{ time ls > /dev/null 2>&1 ; } 2> out.txt

1
ตกลงคำตอบที่ดีที่สุด ช่วยให้คุณมีตัวเลือกในการทิ้งผลลัพธ์ ls และรับเวลา ขอบคุณ ghostdog74
rd42

1
สิ่งนี้ใช้ได้กับ AIX เมื่อไม่มีสิ่งใดสามารถเปลี่ยนทิศทางเอาต์พุตของคำสั่ง "hostent" ได้ ขอขอบคุณ!
Hugo

1
คำชี้แจงเกี่ยวกับ2>กรุณา ฉันจะเรียนรู้สิ่งเหล่านี้ได้ที่ไหน
hello_there_andy

3
ฉันจะทำอย่างไรถ้าฉันต้องการทั้ง> และ 2> ในเวลาเดียวกัน?
Jorge Fernández-Hidalgo

26

เวลาคำสั่งจะส่งเอาต์พุตไปยัง STDERR (แทน STDOUT) นั่นเป็นเพราะคำสั่งที่ดำเนินการตามเวลาตามปกติ (ในกรณีนี้คือ ls) ส่งออกเป็น STDOUT

หากคุณต้องการบันทึกผลลัพธ์ของเวลาให้พิมพ์:

(time ls) 2> filename

ที่จับเฉพาะเอาต์พุตของเวลา แต่เอาต์พุตของ ls ไปที่คอนโซลเป็นปกติ หากคุณต้องการจับภาพทั้งสองในไฟล์เดียวให้พิมพ์:

(time ls) &> filename

2> เปลี่ยนเส้นทาง STDERR &> เปลี่ยนเส้นทางทั้งสอง


1
คำตอบนี้ตอบได้จริงว่าทำไมการเปลี่ยนเส้นทางของ OP จึงไม่ทำงานซึ่งเป็นหนึ่งในคำถามที่ OP ถาม ไม่มีใครพูดถึงเรื่องนี้
NeutronStar

ท่อหนึ่งไปยังกระบวนการอื่นด้วยวิธีนี้อย่างไร
พอล

11

เวลาเป็นเชลล์ในตัวและฉันไม่แน่ใจว่ามีวิธีเปลี่ยนเส้นทางหรือไม่ อย่างไรก็ตามคุณสามารถใช้ /usr/bin/timeแทนได้ซึ่งยอมรับการเปลี่ยนเส้นทางเอาต์พุตอย่างแน่นอน


/ usr / bin / time --output filename ls
chub

4
เวลาในตัวทำงานได้ดีกับการเปลี่ยนทิศทางเอาต์พุต เอาต์พุตเฉพาะบน STDERR ไม่ใช่บน STDOUT
Mnementh

ปัญหาคือคำสั่งในตัวถูกดำเนินการภายในสภาพแวดล้อมเชลล์เองไม่ใช่เชลล์ย่อย เนื่องจากโดยทั่วไปแล้ว stderr ของเชลล์ของคุณจะเชื่อมต่อกับเทอร์มินัลการเปลี่ยนเส้นทางจะไม่ทำอะไรเลย bash time mycmd 2>fileเมื่อต้องการเปลี่ยนเส้นทางเวลาในตัวผมเชื่อว่าคุณจะต้องทำสิ่งที่ชอบ หรือเรียก/usr/bin/timeตามที่กล่าวมา
ktbiz

คุณยังสามารถใช้สิ่งที่ไม่ใช่ในตัวโดยไม่ต้องระบุเส้นทางแบบเต็ม: stackoverflow.com/questions/29540540/…
Ciro Santilli 郝海东冠状病六四事件事件

5

สาเหตุที่ดูเหมือนว่าการเปลี่ยนเส้นทางใช้งานไม่ได้timeคือมันเป็นคำสงวน bash (ไม่ใช่ builtin!) เมื่อใช้หน้าไปป์ไลน์ ทุบตี (1):

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

ดังนั้นหากต้องการเปลี่ยนเส้นทางเอาต์พุตtimeให้ใช้วงเล็บปีกกา:

{ time ls; } 2> filename

หรือโทร/usr/bin/time:

/usr/bin/time ls 2> filename

4

หากคุณไม่ต้องการผสมเอาต์พุตจากtimeและคำสั่ง ด้วยเวลา GNU คุณสามารถใช้-o fileเช่น:

/usr/bin/time -o tim grep -e k /tmp 1>out 2>err

ในขณะที่timเป็นผลลัพธ์ของเวลาoutและerrมี stdout และ stderr grepจาก


0

ฉันใช้วิธีการเปลี่ยนเส้นทางของ stdout และ stderr กับวงเล็บปีกกาสำหรับการทดสอบ หมายถึงนี้แต่สั้น วงเล็บปีกกาจะดำเนินการคำสั่งในเชลล์ปัจจุบัน ดู: man bash
&>>rpt>>rpt 2>&1

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