วิธีเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์บันทึกหลายไฟล์


52

วิธีเปลี่ยนเส้นทางเอาต์พุตมาตรฐานไปยังไฟล์บันทึกหลายไฟล์? ต่อไปนี้ใช้ไม่ได้:

some_command 1> output_log_1 output_log_2 2>&1

6
ด้วยคุณสามารถใช้zsh some_command >output_log_1 >output_log_2
กรกฎาคม

คำตอบ:


70

ดูman tee:

ชื่อ: ที - อ่านจากอินพุตมาตรฐานและเขียนไปยังเอาต์พุตและไฟล์มาตรฐาน

เรื่องย่อ: ที [ตัวเลือก] ... [ไฟล์] ...

ดังนั้น:

echo test | tee file1 file2 file3

สามารถเปลี่ยนเส้นทาง stderr ในมากกว่าหนึ่งไฟล์ได้หรือไม่
fromnaboo

ใช่สามารถทำได้โดยอาศัยการเปลี่ยนเส้นทาง: find / -name test 2> & 1 | ที file1 file2 file3
akond

@akond cmd 2>&1 | tee log1 log2 ฉันพยายามเรียกใช้งานดังกล่าวข้างต้น แต่ฉันต้องกด ctrl-c เพื่อเปลี่ยนเส้นทางไปยังไฟล์บันทึกที่สอง ยังมีการพิมพ์ผลลัพธ์บนคอนโซล ฉันต้องการให้เปลี่ยนเส้นทางคำสั่งไปยังบันทึก แต่ไม่ได้อยู่ในคอนโซล ความช่วยเหลือใด ๆ ที่มีความนิยม
doubledecker

@doubledecker teeคำสั่งเขียนstdinไปยังแฟ้ม (s) และยังstdoutจะ หากคุณไม่ต้องการให้เอาต์พุตปรากฏบนเทอร์มินัลคุณต้องเปลี่ยนเส้นทางไป/dev/nullตามปกติ
Minix

4
นอกจากนี้ยังเป็นไปได้ที่จะผนวกเข้ากับไฟล์หลายไฟล์:echo test | tee --append file1 file2
user1364368

13

สมมติว่าเอาต์พุตของคุณสร้างจากฟังก์ชันcmd():

cmd() {
    echo hello world!
}

ในการเปลี่ยนทิศทางเอาต์พุตจากcmdไฟล์สองไฟล์ แต่ไม่ใช่ไปยังคอนโซลคุณสามารถใช้:

cmd | tee file1 file2 >/dev/null

วิธีนี้จะใช้งานได้กับหลาย ๆ ไฟล์กำหนดให้แหล่งข้อมูลใด ๆ

echo "foobarbaz" | tee file1 file2 file3 file4 > /dev/null

สิ่งนี้จะได้ผล:

echo $(cmd) | tee file1 file2 >/dev/null

หากไม่มีการ/dev/nullเปลี่ยนเส้นทาง tee จะส่งเอาต์พุตไปยัง stdout นอกเหนือจากไฟล์ที่ระบุ

ตัวอย่างเช่นหากสิ่งนี้ถูกเรียกใช้จากคอนโซลคุณจะเห็นผลลัพธ์ที่นั่น เรียกใช้จาก crontab ผลลัพธ์จะปรากฏข้อความสถานะที่ส่งถึงคุณ (ดูคำตอบของ Gilles ได้ที่นี่https://unix.stackexchange.com/a/100833/3998 )

สิ่งนี้ใช้ได้กับฉันในการทุบตีบน Ubuntu 12.04 และได้รับการยืนยันใน Ubuntu 14.04 โดยใช้ GNU bash 4.3.11 (1) ดังนั้นจึงควรใช้กับ GNU ทุบตีรุ่นล่าสุด


@doubledecker - ดูเหมือนว่าจะเป็นไปตามเงื่อนไขของคุณดังนั้นจึงสามารถยอมรับได้ว่าเป็นคำตอบ นอกจากนี้ +1 ที่ฉันทดสอบภายใต้ GNU bash ( version 4.3.11(1)-release (i686-pc-linux-gnu)) ใน Ubuntu 14.04
belacqua

9

มันเป็นโพสต์เก่า แต่ฉันเพิ่งพบตอนนี้ ...

แทนที่จะเปลี่ยนเส้นทางผลลัพธ์ไปที่> /dev/nullคุณสามารถเปลี่ยนเส้นทางไปยังไฟล์สุดท้าย:

echo "foobarbaz" | tee file1 > file2

หรือสำหรับการผนวกเอาต์พุต:

echo "foobarbaz" | tee -a file1 >> file2

นี้จะมากหรือน้อยว่าคำตอบอื่น ๆ กล่าวว่า (ยกเว้น-a ในที)
Archemar

นี่คือวิธีที่จะไป
71GA

5

ดังที่ @jofel พูดถึงในความคิดเห็นภายใต้คำตอบสิ่งนี้สามารถทำได้ในzsh:

echo foobar >file1 >file2 >file3

หรือด้วยการขยายรั้ง:

echo foobar >file{1..3}

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


2

อย่างไรก็ตามไม่สามารถแสดงความคิดเห็นได้อีกวิธีหนึ่งในการแสดง

echo "foobarbaz" | tee file1 file2 file3 file4 file5 file6 file7 file8 > /dev/null

อาจทำให้เรื่องนี้ง่ายขึ้นเมื่อจัดการกับไฟล์จำนวนมาก

echo "foobarbaz" | tee file{1..8} > /dev/null

2
สิ่งนี้แตกต่างจากคำตอบอื่น ๆ ที่ได้ให้ไปแล้วจริง ๆ หรือ? โดยเฉพาะอย่างยิ่งตั้งแต่ไม่กี่คนที่มีแนวโน้มต้องการที่แท้จริงfile1ผ่านfile8เป็นชื่อของพวกเขาและผู้ที่มีแนวโน้มที่จะยึดตำแหน่งเพียงตัวอย่างสำหรับชื่อของไฟล์
เอริค Renouf

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