Làm cách nào để lưu đầu ra của thiết bị đầu cuối vào một tệp?


688

Làm cách nào để lưu đầu ra của lệnh vào tệp?

Có cách nào mà không sử dụng bất kỳ phần mềm nào không? Tôi muốn biết làm thế nào.

Câu trả lời:


735

Có, có thể, chỉ cần chuyển hướng đầu ra thành một tệp:

SomeCommand > SomeFile.txt  

Hoặc nếu bạn muốn nối thêm dữ liệu:

SomeCommand >> SomeFile.txt

Nếu bạn cũng muốn stderrsử dụng điều này:

SomeCommand &> SomeFile.txt  

hoặc cái này để nối thêm:

SomeCommand &>> SomeFile.txt  

nếu bạn muốn có cả hai stderrvà đầu ra được hiển thị trên bàn điều khiển trong một tệp, hãy sử dụng:

SomeCommand 2>&1 | tee SomeFile.txt

(Nếu bạn chỉ muốn đầu ra, bỏ phần 2trên)


15
Lưu ý rằng someCommand 2> someFile.txtsomeCommand 2>> someFile.txtcũng chuyển hướng stterrđến someFile.txt
Slothworks

Tôi đang cố gắng làm điều này với lệnh gcc nhưng nó không hoạt động. Nó hoạt động với các lệnh khác, nhưng không phải lệnh này. Nó chỉ đơn giản là tạo tập tin đầu ra không có gì bên trong nó.
Nikos

@ Nik-Lz Thường thì điều này là do lệnh đang gửi tất cả đầu ra của nó trên stderr. Nếu gcc đang tạo thông báo lỗi, điều này dường như có khả năng. Xem bình luận của Slothworks để biết cách chụp stderr thay vì stdout.
Jonathan Hartley

1
NB: để đưa đầu ra của makelệnh vào một tệp, nó yêu cầu cú pháp này thay vào đó: make > someFile.txt 2>&1(nguồn: linuxquestions.org/questions/linux-newbie-8/ trộm )
Gabriel Staples

Tôi có một vấn đề là nó dừng ghi khi tệp đạt khoảng 8 MB. Đây có phải là một giới hạn được biết đến?
relG

863

Để ghi đầu ra của lệnh vào một tệp, về cơ bản có 10 cách thường được sử dụng.

Tổng quan:

Xin lưu ý rằng n.e.trong cú pháp cột có nghĩa là "không tồn tại".
Có một cách, nhưng nó quá phức tạp để phù hợp với cột. Bạn có thể tìm thấy một liên kết hữu ích trong phần Danh sách về nó.

          || 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

Danh sách:

  • command > output.txt

    Luồng đầu ra tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, nó sẽ không hiển thị trong thiết bị đầu cuối. Nếu tập tin đã tồn tại, nó sẽ bị ghi đè.

  • command >> output.txt

    Luồng đầu ra tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, nó sẽ không hiển thị trong thiết bị đầu cuối. Nếu tệp đã tồn tại, dữ liệu mới sẽ được thêm vào cuối tệp.

  • command 2> output.txt

    Luồng lỗi tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, nó sẽ không hiển thị trong thiết bị đầu cuối. Nếu tập tin đã tồn tại, nó sẽ bị ghi đè.

  • command 2>> output.txt

    Luồng lỗi tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, nó sẽ không hiển thị trong thiết bị đầu cuối. Nếu tệp đã tồn tại, dữ liệu mới sẽ được thêm vào cuối tệp.

  • command &> output.txt

    Cả đầu ra tiêu chuẩn và luồng lỗi tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, không có gì hiển thị trong thiết bị đầu cuối. Nếu tập tin đã tồn tại, nó sẽ bị ghi đè.

  • command &>> output.txt

    Cả đầu ra tiêu chuẩn và luồng lỗi tiêu chuẩn sẽ chỉ được chuyển hướng đến tệp, không có gì hiển thị trong thiết bị đầu cuối. Nếu tệp đã tồn tại, dữ liệu mới sẽ được thêm vào cuối tệp ..

  • command | tee output.txt

    Luồng đầu ra tiêu chuẩn sẽ được sao chép vào tập tin, nó sẽ vẫn hiển thị trong thiết bị đầu cuối. Nếu tập tin đã tồn tại, nó sẽ bị ghi đè.

  • command | tee -a output.txt

    Luồng đầu ra tiêu chuẩn sẽ được sao chép vào tập tin, nó sẽ vẫn hiển thị trong thiết bị đầu cuối. Nếu tệp đã tồn tại, dữ liệu mới sẽ được thêm vào cuối tệp.

  • (*)

    Bash không có cú pháp tốc ký cho phép chỉ đưa StdErr vào lệnh thứ hai, điều này sẽ cần ở đây kết hợp với teemột lần nữa để hoàn thành bảng. Nếu bạn thực sự cần một cái gì đó như thế, xin vui lòng xem "Làm thế nào để ống stderr, và không stdout?" trên Stack Overflow đối với một số cách làm thế nào điều này có thể được thực hiện, ví dụ bằng cách hoán đổi luồng hoặc sử dụng thay thế quy trình.

  • command |& tee output.txt

    Cả hai luồng đầu ra tiêu chuẩn và lỗi tiêu chuẩn sẽ được sao chép vào tệp trong khi vẫn hiển thị trong thiết bị đầu cuối. Nếu tập tin đã tồn tại, nó sẽ bị ghi đè.

  • command |& tee -a output.txt

    Cả hai luồng đầu ra tiêu chuẩn và lỗi tiêu chuẩn sẽ được sao chép vào tệp trong khi vẫn hiển thị trong thiết bị đầu cuối. Nếu tệp đã tồn tại, dữ liệu mới sẽ được thêm vào cuối tệp.


66
Cảm ơn vì cái bàn, thật tuyệt vời! Đây phải là câu trả lời hàng đầu
DevShark

3
@ karthick87 Điều này không thực sự liên quan đến câu hỏi về việc chuyển hướng đầu ra sang một tệp, bởi vì nó chỉ chuyển hướng một luồng này sang luồng khác. 2>&1chuyển hướng STDERR sang STDOUT, 1>&2chuyển hướng STDOUT sang STDERR và 3>&1sẽ chuyển hướng luồng 3 sang STDERR.
Chỉ huy Byte

18
Chỉ cần một lưu ý rằng '| &' không hoạt động với tôi trên macOS. Điều này là do nó có một phiên bản bash cũ hơn (tôi nghĩ). '2> & 1 |' kém thanh lịch hoạt động tốt mặc dù
Daniel Parker

2
@ByteCommander Tôi gặp lỗi: sh: 1: Syntax error: "&" unexpectedkhi tôi sử dụng |& teetừ tập lệnh Python trong máy chủ c9.io. Có vẻ như một vỏ khác đang được sử dụng. echo $SHELLhiển thị /bin/bash$SHELL --versionhiển thị phiên bản 4.3.11 (1). Tôi đã thử #!/bin/bashtrong kịch bản python của tôi nhưng tôi vẫn nhận được sh: 1: Syntax error. Tôi đã nhận được những gì tôi cần vì vậy tôi đang từ bỏ việc sắp xếp sự kỳ lạ giữa shbashtrên máy chủ của mình. Cảm ơn.
samkhan13

1
@ samkhan13 có vẻ như bạn đang chạy shvà không bash(hoặc có thể bashshchế độ ...). Bạn có thể kiểm tra chính xác quá trình shell hiện tại của bạn đang sử dụng là gì ps -p $$ -o cmd=, bởi vì echo $SHELLnó không đáng tin cậy và sẽ hiển thị cho bạn shell đăng nhập của bạn, bỏ qua liệu bạn có thể đã bắt đầu một subshell khác hay không.
Chỉ huy Byte

108

Bạn cũng có thể sử dụng teeđể gửi đầu ra tới một tệp:

command | tee ~/outputfile.txt

Một sửa đổi nhỏ cũng sẽ bắt được stderr:

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

hoặc ngắn hơn một chút và ít phức tạp hơn:

command |& tee ~/outputfile.txt

teelà hữu ích nếu bạn muốn có thể chụp đầu ra lệnh trong khi xem nó trực tiếp .


Nó nói rằng & là bất ngờ, và không viết nhật ký cùng lúc với lệnh chạy. Tôi đang sử dụng điều này trong một tập tin bash, tuy nhiên, điều đó có làm nên sự khác biệt nào không?
tim687

@ tim687 Tôi đã gỡ bỏ chỉnh sửa đó. Xin lỗi về điều đó ... không phải là một phần của câu trả lời ban đầu của tôi.
Aaron

@Aaron Cảm ơn! tee sẽ nối các tập tin trong thời gian thực, phải không? Tôi có một tập lệnh sao lưu mà tôi sử dụng để, lol, sao lưu máy tính của tôi, nhưng việc đăng nhập không theo thời gian thực. Máy tính của tôi chuyển sang chế độ ngủ sau khi sao lưu xong và tệp nhật ký trống. Tôi có nên sử dụng một lệnh khác để đăng nhập các lệnh?
tim687

Làm thế nào để tôi giải thích ý nghĩa của 2>&1?
Mahesha999

@ Mahesha999 2 là bộ mô tả tệp cho STDERR và 1 là cho STDOUT. Vì vậy, 2> & 1 gửi STDERR đến STDOUT. Câu hỏi SO này giải thích nó khá hay: stackoverflow.com/questions/818255/ Kẻ
Aaron

20

Bạn có thể chuyển hướng đầu ra lệnh đến một tệp:

your_command >/path/to/file

Để nối đầu ra lệnh vào một tệp thay vì ghi đè lên nó, hãy sử dụng:

your_command >>/path/to/file

Cảm ơn rất nhiều ! Có giới hạn nào không? như kích thước tối đa của tập tin?
đã dẫn-Zepp

3
Kích thước tệp tối đa chỉ bị giới hạn thông qua hệ thống tệp
hỗn loạn

Câu trả lời này sẽ không lưu stderr. Sử dụng &>, xem stackoverflow.com/questions/637827/ và và tldp.org/LDP/abs/html/io-redirection.html
Panther

3
OP không bao giờ yêu cầu tiết kiệm stderr
hỗn loạn

Nó nói "Không có tập tin hoặc thư mục như vậy". Có thể cũng tạo các thư mục tự động?
Qwerty

14

Một cải tiến để xem xét -

Các tập lệnh khác nhau sẽ đưa mã màu vào đầu ra mà bạn có thể không muốn làm lộn xộn tệp nhật ký của mình.

Để khắc phục điều này, bạn có thể sử dụng chương trình sed để loại bỏ các mã đó. Thí dụ:

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

1
Làm thế nào để tiết kiệm đầu ra theo cách mà màu sắc được bảo tồn? Tôi muốn nhập kết quả của một lệnh trong libreoffice và giữ màu.
madrang

@madrang: Tôi chỉ đọc bình luận của bạn bây giờ nhưng bạn có thể thấy câu trả lời này hữu ích.
Sylvain Pineau

Ồ, gần như chính xác những gì tôi đang tìm kiếm. Làm thế nào để in cũng trên màn hình đầu ra?
Sigur

1
Lưu ý rằng nhiều lệnh tạo đầu ra được tô màu, chẳng hạn như lsgrep, hỗ trợ --color=auto, chỉ xuất mã màu nếu đầu ra tiêu chuẩn là đầu cuối.
Eliah Kagan

5

Đối với croncông việc, vv bạn muốn tránh các phần mở rộng Bash. Các shtoán tử chuyển hướng POSIX tương đương là

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

Bạn sẽ nhận thấy rằng cơ sở POSIX theo một nghĩa nào đó đơn giản và đơn giản hơn. Các &>cú pháp được mượn từ cshđó nên đã thuyết phục bạn rằng đó là một ý tưởng tồi.


1

some_command | tee command.logsome_command > command.logcó vấn đề là họ không lưu đầu ra lệnh vào command.logtệp trong thời gian thực.

Để tránh vấn đề đó và lưu đầu ra lệnh trong thời gian thực, bạn có thể nối thêm unbuffer, đi kèm với expectgói.


Thí dụ:

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

Giả sử log.pycó chứa:

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

bạn có thể chạy unbuffer python log.py | tee command.loghoặcunbuffer python log.py > command.log

Thông tin thêm: Làm cách nào tôi có thể lưu một đầu ra lệnh vào một tệp trong thời gian thực?


Họ lưu đầu ra khi họ nhận được, vấn đề là python bật bộ đệm khi đầu ra không phải là TTY. Các tùy chọn khác để vô hiệu hóa điều này trong Python: stackoverflow.com/q/107705/2072269
muru
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.