ฉันจะบันทึกผลลัพธ์เทอร์มินัลลงในไฟล์ได้อย่างไร


688

ฉันจะบันทึกเอาต์พุตของคำสั่งไปยังไฟล์ได้อย่างไร?

มีวิธีโดยไม่ใช้ซอฟต์แวร์ใด ๆ ? ฉันต้องการทราบวิธีการ

คำตอบ:


735

ใช่มันเป็นไปได้เพียงแค่เปลี่ยนเส้นทางการส่งออกไปยังไฟล์:

SomeCommand > SomeFile.txt  

หรือถ้าคุณต้องการผนวกข้อมูล:

SomeCommand >> SomeFile.txt

ถ้าคุณต้องการstderrใช้เช่นนี้:

SomeCommand &> SomeFile.txt  

หรือสิ่งนี้เพื่อผนวก:

SomeCommand &>> SomeFile.txt  

หากคุณต้องการให้ทั้งสองstderrและเอาท์พุทแสดงบนคอนโซลและในไฟล์ใช้สิ่งนี้:

SomeCommand 2>&1 | tee SomeFile.txt

(ถ้าคุณต้องการเอาท์พุทเท่านั้นวาง2ด้านบน)


15
โปรดทราบว่าsomeCommand 2> someFile.txtและsomeCommand 2>> someFile.txtยังเปลี่ยนเส้นทางstterrไปยัง someFile.txt
Slothworks

ฉันพยายามทำสิ่งนี้ด้วยคำสั่ง gcc แต่มันไม่ทำงาน มันใช้งานได้กับคำสั่งอื่น แต่ไม่ใช่อันนี้ มันสร้างไฟล์เอาต์พุตโดยไม่มีอะไรอยู่ข้างใน
Nikos

@ Nik-Lz บ่อยครั้งนี่เป็นเพราะคำสั่งกำลังส่งเอาต์พุตทั้งหมดบน stderr หาก gcc กำลังสร้างข้อความแสดงข้อผิดพลาดน่าจะเป็นเช่นนี้ ดูความคิดเห็น Slothworks สำหรับวิธีการจับ stderr แทน stdout
Jonathan Hartley

1
หมายเหตุ: เพื่อให้ได้ผลลัพธ์ของmakeคำสั่งลงในไฟล์มันต้องใช้ไวยากรณ์นี้แทน: make > someFile.txt 2>&1(ที่มา: linuxquestions.org/questions/linux-newbie-8/… )
Gabriel Staples

ฉันมีปัญหาที่จะหยุดเขียนเมื่อไฟล์ถึงประมาณ 8MB นี่เป็นขีด จำกัด ที่รู้จักหรือไม่?
relG

863

ในการเขียนเอาต์พุตของคำสั่งไปยังไฟล์นั้นมี 10 วิธีที่ใช้กันทั่วไป

ข้อมูลทั่วไป:

โปรดทราบว่าn.e.ในคอลัมน์ไวยากรณ์หมายถึง "ไม่มีอยู่"
มีวิธี แต่มันซับซ้อนเกินไปที่จะใส่ลงในคอลัมน์ คุณสามารถค้นหาลิงค์ที่มีประโยชน์ในส่วนรายการเกี่ยวกับมัน

          || visible in terminal ||   visible in file   || existing
  Syntax  ||  StdOut  |  StdErr  ||  StdOut  |  StdErr  ||   file   
==========++==========+==========++==========+==========++===========
    >     ||    no    |   yes    ||   yes    |    no    || overwrite
    >>    ||    no    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
   2>     ||   yes    |    no    ||    no    |   yes    || overwrite
   2>>    ||   yes    |    no    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
   &>     ||    no    |    no    ||   yes    |   yes    || overwrite
   &>>    ||    no    |    no    ||   yes    |   yes    ||  append
          ||          |          ||          |          ||
 | tee    ||   yes    |   yes    ||   yes    |    no    || overwrite
 | tee -a ||   yes    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    || overwrite
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
|& tee    ||   yes    |   yes    ||   yes    |   yes    || overwrite
|& tee -a ||   yes    |   yes    ||   yes    |   yes    ||  append

รายการ:

  • command > output.txt

    สตรีมเอาต์พุตมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่สามารถมองเห็นได้ในเทอร์มินัล หากไฟล์มีอยู่แล้วไฟล์นั้นจะถูกเขียนทับ

  • command >> output.txt

    สตรีมเอาต์พุตมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่สามารถมองเห็นได้ในเทอร์มินัล หากไฟล์มีอยู่แล้วข้อมูลใหม่จะถูกต่อท้ายไฟล์

  • command 2> output.txt

    สตรีมข้อผิดพลาดมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่ปรากฏในเทอร์มินัล หากไฟล์มีอยู่แล้วไฟล์นั้นจะถูกเขียนทับ

  • command 2>> output.txt

    สตรีมข้อผิดพลาดมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่ปรากฏในเทอร์มินัล หากไฟล์มีอยู่แล้วข้อมูลใหม่จะถูกต่อท้ายไฟล์

  • command &> output.txt

    ทั้งเอาต์พุตมาตรฐานและสตรีมข้อผิดพลาดมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่มีสิ่งใดปรากฏในเทอร์มินัล หากไฟล์มีอยู่แล้วไฟล์นั้นจะถูกเขียนทับ

  • command &>> output.txt

    ทั้งเอาต์พุตมาตรฐานและสตรีมข้อผิดพลาดมาตรฐานจะถูกเปลี่ยนเส้นทางไปยังไฟล์เท่านั้นจะไม่มีสิ่งใดปรากฏในเทอร์มินัล หากไฟล์มีอยู่แล้วข้อมูลใหม่จะถูกต่อท้ายไฟล์

  • command | tee output.txt

    สตรีมเอาต์พุตมาตรฐานจะถูกคัดลอกไปยังไฟล์ซึ่งจะยังคงปรากฏให้เห็นในเทอร์มินัล หากไฟล์มีอยู่แล้วไฟล์นั้นจะถูกเขียนทับ

  • command | tee -a output.txt

    สตรีมเอาต์พุตมาตรฐานจะถูกคัดลอกไปยังไฟล์ซึ่งจะยังคงปรากฏให้เห็นในเทอร์มินัล หากไฟล์มีอยู่แล้วข้อมูลใหม่จะถูกต่อท้ายไฟล์

  • (*)

    Bash ไม่มีไวยากรณ์จดชวเลขที่อนุญาตให้วางเฉพาะ StdErr ไปยังคำสั่งที่สองซึ่งจำเป็นต้องใช้ร่วมกับteeอีกครั้งเพื่อทำให้ตารางเสร็จสมบูรณ์ หากคุณต้องการอะไรแบบนั้นจริงๆโปรดดูที่"จะไปป์ stderr อย่างไรและไม่ใช่ stdout" บน Stack Overflowสำหรับวิธีการนี้สามารถทำได้เช่นโดยการสลับการสตรีมหรือการใช้การทดแทนกระบวนการ

  • command |& tee output.txt

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

  • command |& tee -a output.txt

    ทั้งเอาต์พุตมาตรฐานและสตรีมข้อผิดพลาดมาตรฐานจะถูกคัดลอกไปยังไฟล์ในขณะที่ยังคงมองเห็นได้ในเทอร์มินัล หากไฟล์มีอยู่แล้วข้อมูลใหม่จะถูกต่อท้ายไฟล์


66
ขอบคุณสำหรับตารางมันยอดเยี่ยมมาก! นี่ควรเป็นคำตอบที่ดีที่สุด
DevShark

3
@ karthick87 สิ่งนี้ไม่เกี่ยวข้องกับคำถามเกี่ยวกับการเปลี่ยนทิศทางเอาต์พุตไปยังไฟล์เพราะมันจะเปลี่ยนเส้นทางสตรีมหนึ่งไปยังสตรีมอื่น 2>&1เปลี่ยนเส้นทาง STDERR ไปยัง STDOUT 1>&2เปลี่ยนเส้นทาง STDOUT ไปยัง STDERR และ3>&1จะเปลี่ยนเส้นทางสตรีม 3 ไปยัง STDERR
ผู้บัญชาการ Byte

18
แค่ทราบว่า '| &' ไม่ได้ทำงานกับฉันใน macOS นี่เป็นเพราะมันมีทุบตีรุ่นเก่ากว่า (ฉันคิดว่า) สง่าน้อย '2> & 1 |' ทำงานได้ดีแม้ว่า
Danny Parker

2
@ ByteCommander ฉันได้รับข้อผิดพลาด: sh: 1: Syntax error: "&" unexpectedเมื่อฉันใช้|& teeจากสคริปต์ Python ในเซิร์ฟเวอร์ c9.io ดูเหมือนว่ามีการใช้เปลือกที่แตกต่างกัน echo $SHELLแสดง/bin/bashและ$SHELL --versionแสดงเวอร์ชัน 4.3.11 (1) - ปล่อย ฉันพยายาม#!/bin/bashในสคริปต์หลามของฉัน sh: 1: Syntax errorแต่ฉันยังคงได้รับ ฉันได้สิ่งที่ฉันต้องการดังนั้นฉันจึงยอมแพ้ในการคัดแยกความแปลกประหลาดระหว่างshและbashบนเซิร์ฟเวอร์ของฉัน ขอบคุณ
samkhan13

1
@ samkhan13 ดูเหมือนว่าคุณกำลังใช้งานอยู่shและไม่ใช่bash(หรืออาจbashอยู่ในshโหมด ... ) คุณสามารถตรวจสอบว่ากระบวนการเชลล์ปัจจุบันของคุณกำลังใช้ps -p $$ -o cmd=งานecho $SHELLอะไรอยู่เพราะไม่น่าเชื่อถือและจะแสดงเชลล์ล็อกอินให้คุณโดยไม่สนใจว่าคุณอาจเริ่มเชลล์ย่อยอื่นหรือไม่
ผู้บัญชาการไบต์

108

คุณยังสามารถใช้teeเพื่อส่งออกไปยังไฟล์:

command | tee ~/outputfile.txt

การปรับเปลี่ยนเล็กน้อยจะจับ stderr เช่นกัน:

command 2>&1 | tee ~/outputfile.txt

หรือสั้นกว่าเล็กน้อยและซับซ้อนน้อยกว่า:

command |& tee ~/outputfile.txt

teeจะเป็นประโยชน์ถ้าคุณต้องการที่จะสามารถที่จะจับออกคำสั่งในขณะที่ยังดูมันอยู่


มันบอกว่า & & ไม่คาดคิดและไม่ได้เขียนบันทึกในเวลาเดียวกันกับที่คำสั่งทำงาน ฉันกำลังใช้สิ่งนี้ในไฟล์ bash แต่นั่นสร้างความแตกต่างหรือไม่?
tim687

@ tim687 ฉันได้ลบการแก้ไขนั้น ขออภัยที่ ... ไม่ได้เป็นส่วนหนึ่งของคำตอบเดิมของฉัน
แอรอน

@Aaron ขอบคุณ! tee จะต่อท้ายไฟล์แบบเรียลไทม์ใช่ไหม ฉันมีสคริปต์สำรองที่ฉันใช้กับฮ่า ๆ ๆ สำรองข้อมูลพีซีของฉัน แต่การบันทึกไม่ได้ตามเวลาจริง พีซีของฉันเข้าสู่โหมดสลีปหลังจากการสำรองข้อมูลเสร็จสิ้นและไฟล์บันทึกว่างเปล่า ฉันควรใช้คำสั่งอื่นเพื่อบันทึกคำสั่งหรือไม่?
tim687

ฉันจะตีความความหมายของได้2>&1อย่างไร
Mahesha999

@ Mahesha999 2 เป็นตัวอธิบายไฟล์สำหรับ STDERR และ 1 สำหรับ STDOUT ดังนั้น 2> & 1 จึงส่ง STDERR ไปยัง STDOUT คำถาม SO นี้อธิบายได้ค่อนข้างดี: stackoverflow.com/questions/818255/…
Aaron

20

คุณสามารถเปลี่ยนเส้นทางผลลัพธ์คำสั่งไปยังไฟล์:

your_command >/path/to/file

ในการผนวกเอาต์พุตคำสั่งต่อท้ายไฟล์แทนที่จะเขียนทับมันให้ใช้:

your_command >>/path/to/file

ขอบคุณมาก ! มีข้อ จำกัด หรือไม่? ชอบขนาดสูงสุดของไฟล์หรือไม่
led-Zepp

3
ขนาดไฟล์สูงสุดที่ถูก จำกัด เพียงผ่านระบบแฟ้ม
ความวุ่นวาย

คำตอบนี้จะไม่บันทึก stderr ใช้ &> ดูstackoverflow.com/questions/637827/…และtldp.org/LDP/abs/html/io-redirection.html
Panther

3
OP ไม่เคยขอให้ช่วย stderr
ความโกลาหล

มีข้อความระบุว่า "ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว" เป็นไปได้ไหมที่จะสร้างไดเรกทอรีโดยอัตโนมัติ?
Qwerty

14

การปรับปรุงที่จะต้องพิจารณา -

สคริปต์ต่าง ๆ จะใส่รหัสสีลงในผลลัพธ์ซึ่งคุณอาจไม่ต้องการให้ไฟล์บันทึกของคุณยุ่งเหยิง

หากต้องการแก้ไขปัญหานี้คุณสามารถใช้โปรแกรมsedจะตัดออกรหัสเหล่านั้น ตัวอย่าง:

command 2>&1 | sed -r 's/'$(echo -e "\033")'\[[0-9]{1,2}(;([0-9]{1,2})?)?[mK]//g' | tee ~/outputfile.txt

1
จะบันทึกเอาต์พุตในแบบที่อนุรักษ์สีได้อย่างไร? ฉันต้องการนำเข้าผลลัพธ์ของคำสั่งใน libreoffice และเก็บสีไว้
madrang

@madrang: ฉันแค่อ่านความคิดเห็นของคุณตอนนี้ แต่คุณอาจพบว่าคำตอบนี้มีประโยชน์
Sylvain Pineau

โอ้เกือบสิ่งที่ฉันกำลังมองหา วิธีการพิมพ์บนหน้าจอเอาท์พุท?
Sigur

1
โปรดทราบว่าคำสั่งจำนวนมากที่สร้างเอาต์พุตที่เป็นสีเช่นlsและgrepรองรับ--color=autoซึ่งเอาต์พุตโค้ดสีเฉพาะเมื่อเอาต์พุตมาตรฐานคือเทอร์มินัล
Eliah Kagan

5

สำหรับcronงานอื่น ๆ ที่คุณต้องการหลีกเลี่ยง Bash extension ตัวshดำเนินการเปลี่ยนเส้นทางPOSIX ที่เทียบเท่าคือ

Bash          POSIX
------------  --------------
foo &> bar    foo >bar 2>&1
foo &>> bar   foo >>bar 2>&1
foo |& bar    foo 2>&1 | bar

คุณจะสังเกตเห็นว่าสิ่งอำนวยความสะดวก POSIX นั้นเรียบง่ายและตรงไปตรงมามากกว่า &>ไวยากรณ์ที่ถูกยืมมาจากcshที่แล้วควรโน้มน้าวให้คุณว่ามันเป็นความคิดที่ดี


1

some_command | tee command.logและsome_command > command.logมีปัญหาที่พวกเขาไม่ได้บันทึกเอาท์พุทคำสั่งลงในcommand.logไฟล์แบบเรียลไทม์

เพื่อหลีกเลี่ยงปัญหาดังกล่าวและบันทึกผลลัพธ์คำสั่งแบบเรียลไทม์คุณอาจผนวกunbufferซึ่งมาพร้อมกับexpectแพ็คเกจ


ตัวอย่าง:

sudo apt-get install expect
unbuffer some_command | tee command.log
unbuffer some_command > command.log

สมมติว่าlog.pyประกอบด้วย:

import time
print('testing')
time.sleep(100) # sleeping for 100 seconds

คุณสามารถเรียกใช้unbuffer python log.py | tee command.logหรือunbuffer python log.py > command.log

ข้อมูลเพิ่มเติม: ฉันจะบันทึกเอาต์พุตคำสั่งลงในไฟล์แบบเรียลไทม์ได้อย่างไร?


พวกเขาบันทึกเอาต์พุตตามที่ได้รับปัญหาคือ python เปิดการบัฟเฟอร์เมื่อเอาต์พุตไม่ได้เป็น TTY ตัวเลือกอื่น ๆ สำหรับการปิดใช้งานสิ่งนี้ใน Python: stackoverflow.com/q/107705/2072269
muru
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.