1392

How do I save the output of a command to a file?

Is there a way without using any software? I would like to know how.

kiri
  • 28,246
  • 16
  • 81
  • 118
led-Zepp
  • 14,195
  • 5
  • 16
  • 12

11 Answers11

1718

Yes it is possible, just redirect the output (AKA stdout) to a file:

SomeCommand > SomeFile.txt  

Or if you want to append data:

SomeCommand >> SomeFile.txt

If you want stderr as well use this:

SomeCommand &> SomeFile.txt  

or this to append:

SomeCommand &>> SomeFile.txt  

if you want to have both stderr and output displayed on the console and in a file use this:

SomeCommand 2>&1 | tee SomeFile.txt

(If you want the output only, drop the 2 above)

Pablo Bianchi
  • 15,657
Seth
  • 58,122
  • 41
    Note that someCommand 2> someFile.txt and someCommand 2>> someFile.txt also redirects stterr to someFile.txt – Slothworks Aug 29 '15 at 13:32
  • I'm trying to do this with gcc command but it doesn't work. It works with other commands, but not this one. It simply creates the output file with nothing inside it. – KeyC0de Sep 29 '16 at 13:40
  • @Nik-Lz Often this is because the command is sending all its output on stderr. If gcc is generating error messages, this seems likely. See Slothworks comment for how to capture stderr instead of stdout. – Jonathan Hartley Sep 14 '17 at 13:29
  • 1
    NB: to get the output of the make command into a file it requires this syntax instead: make > someFile.txt 2>&1 (source: https://www.linuxquestions.org/questions/linux-newbie-8/redirecting-make-output-to-file-594997/#post2938625) – Gabriel Staples Jan 15 '18 at 00:49
  • 1
    I have a problem that it stops writing when the file reaches about 8MB. Is this a known limit? – relG Oct 27 '18 at 08:02
  • @relG Please specify exactly which method you are using above. The whole command would be better. – Seth Oct 27 '18 at 20:30
  • @Seth: SomeCommand > output.txt – relG Oct 28 '18 at 00:51
  • what if your text is a copy paste into the terminal and it's a bunch of formatted code? – Urasquirrel Apr 28 '20 at 22:45
  • @Urasquirrel I don’t understand your question. Could you elaborate? – Seth Apr 28 '20 at 22:57
  • @Seth, is there a faster way to do the same? – kalpaj agrawalla Aug 18 '20 at 15:09
  • @kalpajagrawalla Faster way to do what? – Seth Aug 20 '20 at 00:34
  • redirecting output to a file (I have a C++ program, whose output (10^5 lines of strings, each in a new line), I wish to redirect to a file, but using the above solutions, my laptop hangs. – kalpaj agrawalla Aug 20 '20 at 05:31
  • @kalpajagrawalla Sounds like a hardware limitation. You're asking your machine to write 100,000 lines at once, while your app is doing its thing. I'd try just waiting it out. – Seth Aug 20 '20 at 23:55
  • &>> is giving error – Maveňツ Jan 23 '23 at 08:43
  • Thank you very much! I finally understood the difference between > and >> :-) – Gill-Bates Aug 25 '23 at 09:57
1580

To write the output of a command to a file, there are basically 10 commonly used ways.

Overview:

Please note that the n.e. in the syntax column means "not existing".
There is a way, but it's too complicated to fit into the column. You can find a helpful link in the List section about it.

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

List:

  • command > output.txt

    The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.

  • command >> output.txt

    The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • command 2> output.txt

    The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.

  • command 2>> output.txt

    The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • command &> output.txt

    Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, it gets overwritten.

  • command &>> output.txt

    Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, the new data will get appended to the end of the file..

  • command | tee output.txt

    The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, it gets overwritten.

  • command | tee -a output.txt

    The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • (*)

    Bash has no shorthand syntax that allows piping only StdErr to a second command, which would be needed here in combination with tee again to complete the table. If you really need something like that, please look at "How to pipe stderr, and not stdout?" on Stack Overflow for some ways how this can be done e.g. by swapping streams or using process substitution.

  • command |& tee output.txt

    Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, it gets overwritten.

  • command |& tee -a output.txt

    Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

Byte Commander
  • 107,489
  • 107
    Thanks for the table, it's excellent! This should be top answer – DevShark Aug 15 '16 at 16:24
  • Great information! Can you also add the details of 2>&1 / 1>&2 / 3>&1 ? – karthick87 Sep 19 '16 at 16:30
  • 3
    @karthick87 This is not really related to the question about redirecting output to a file, because it just redirects one stream to another. 2>&1 redirects STDERR to STDOUT, 1>&2 redirects STDOUT to STDERR and 3>&1 would redirect stream 3 to STDERR. – Byte Commander Sep 19 '16 at 16:42
  • 25
    Just a note that '|&' wasn't working for me on macOS. This is due to it having an older version of bash (I think). The less elegant '2>&1 |' works fine though – Danny Parker May 09 '17 at 10:01
  • |& did not work for me on GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu). 2>&1 | tee produced the desired output of StdOut and StdErr to given file. – samkhan13 Jan 27 '18 at 12:54
  • @samkhan13 |& should be included in Bash since version 4.0 as synonym for 2>&1 |. I believe you either mistyped something in the command, have another Bash version than you claim, or tested it in a different shell, like sh instead of Bash. Are you really sure? – Byte Commander Jan 27 '18 at 19:03
  • 2
    @ByteCommander I get the error: sh: 1: Syntax error: "&" unexpected when I use |& tee from a Python script in a c9.io server. It seems a different shell is being used. echo $SHELL shows /bin/bash and $SHELL --version shows version 4.3.11(1)-release. I tried #!/bin/bash in my python script but I still get sh: 1: Syntax error. I got what I needed so I'm giving up on sorting the weirdness between sh and bash on my server. Thanks. – samkhan13 Jan 28 '18 at 03:09
  • 1
    @samkhan13 looks like you are running sh and not bash (or maybe bash in sh mode...). You can check what exactly your current shell process is using ps -p $$ -o cmd=, because echo $SHELL is unreliable and will show you your login shell, ignoring whether you might have started a different subshell. – Byte Commander Jan 28 '18 at 12:35
  • Also &>> does not work with bash(I'm on Mac), so I had to change it to >> log.txt 2>&1 – Caner Apr 11 '18 at 12:29
  • @Caner It definitely works with modern Bash versions, like 4.3.48 as it is currently used by Ubuntu 16.04, and can be found in the official documentation. Your Mac probably has an older version of Bash which doesn't have this feature yet, but note that this site is only about Ubuntu anyway. – Byte Commander Apr 11 '18 at 12:35
  • 1
    what about n,y,y,y ? – user1133275 May 20 '18 at 12:25
  • @user1133275 That is quite complicated, but you can do something like { YOUR_COMMAND | tee -a FILE.TXT ;} 2>&1 1>/dev/null | tee -a FILE.TXT - this first copies stdout and appends it to your file, then redirects stderr to stdout and disacrds the old stdout, then again copies and appends the new stdout (the redirected stderr) and appends it to your file too. This approach will probably mess up the line order of the two streams though... not sure. Try it out. – Byte Commander May 20 '18 at 14:08
  • What is the meaning of & at |& tee ? – Jas Jun 19 '18 at 05:37
  • 1
    @Jas to redirect both stderr (2) and stdout (1) streams. – Byte Commander Jun 19 '18 at 06:59
  • Is &> the same thing as >&? – Pro Q Jul 13 '18 at 23:00
  • @ProQ Not sure, but seems like it. Didn't think that would work too. – Byte Commander Jul 13 '18 at 23:15
  • Does this apply to make output redirection too? – Danijel Jul 24 '18 at 08:44
  • @Danijel All applications that write to the terminal have to use the same StdOut and StdErr streams (unless maybe some very rare and specific exceptions), so you can use the same redirection mechanisms. For make it surely works as well. Btw, you could also just have tried it... – Byte Commander Jul 24 '18 at 09:36
  • @ByteCommander There was a note somewhere that triggered me to ask: "if you use make do it like this: make > file.txt 2>&1 ". – Danijel Jul 24 '18 at 09:43
  • In a modern Bash, &> file is a shorthand for > file 2>&1 @Danijel . Your version is still correct as well though, and recommended if you need to support other or older shells. – Byte Commander Jul 24 '18 at 10:26
  • For those Mac users with old bash versions, run brew upgrade bash to get to the most recent version. (Trust me, it's worth the time) – Connor McCormick May 16 '19 at 21:21
  • &> works for me to redirect all outputs to different place instead of terminal. – EsmaeelE Aug 30 '19 at 22:19
  • You should add 2>&1 option in your table ;) – Olivier Pons Dec 05 '19 at 09:06
  • Thanks for your answer, and what about with nohup. can we add nohup and & on the head and end directly? – DennisLi Dec 17 '20 at 09:58
  • n.e. (*) is simple: 2> >(tee -a stderr.log >&2). (Don't forget the space.) By the way, thanks for |& --didn't know about that one. – Angelo Aug 04 '21 at 07:03
  • I think better way is command 2>&1 | tee ~/outputfile.txt rather than \& – Exploring Aug 06 '21 at 22:45
  • syntax error near unexpected token `>' while using &>> – Maveňツ Jan 23 '23 at 08:44
  • You could also add 2> | tee file.txt to only have StdOut without StdErr on both terminal and file. – André Casal Mar 07 '23 at 10:00
138

You can also use tee to send the output to a file:

command | tee ~/outputfile.txt

A slight modification will catch stderr as well:

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

or slightly shorter and less complicated:

command |& tee ~/outputfile.txt

tee is useful if you want to be able to capture command output while also viewing it live.

David Foerster
  • 36,264
  • 56
  • 94
  • 147
Aaron
  • 6,714
  • It says that the & is unexpected, and doesn't write the log at the same time as the command runs. I am using this in a bash file however, does that make any difference? – tim687 Apr 06 '16 at 13:51
  • @tim687 I have removed that edit. Sorry about that...wasn't a part of my original answer. – Aaron Apr 06 '16 at 14:11
  • @Aaron Thanks! tee will append the file in real time, right? I have a backup script that I use to,lol , backup my pc, but the logging is not in real time. My pc goes to sleep after the backup is finished, and the log file is empty. Should I use another command to log the commands? – tim687 Apr 07 '16 at 06:43
  • 1
    how do I interpret meaning of 2>&1? – Mahesha999 Jul 15 '16 at 07:47
  • 3
    @Mahesha999 2 is the file descriptor for STDERR, and 1 is for STDOUT. So that 2>&1 sends STDERR to STDOUT. This SO question explains it pretty well: http://stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean – Aaron Jul 15 '16 at 07:53
  • 1
    Instead of 2>&1 |, one can also simply use |&. – Byte Commander Oct 07 '16 at 17:47
  • This approach nicely handles commands with prompts. Thank you very much! – Bower Jan 08 '18 at 14:36
  • @tim687 You're probably not using Bash, or you're using a super old version of Bash. – wjandrea Sep 20 '19 at 22:14
  • on ubuntu 20.04 , I have a problem with 2>&1 . when I use it , I can't capture the java exceptions on the console . But with |& and tee , all is captured in the file – kommradHomer Nov 05 '20 at 09:24
  • The |& tee does not work live for me. I only get the output to the terminal only after execution completes. – S P Sharan Nov 11 '22 at 01:21
24

The script command

There are two different questions here. The first is in the title:

How do I save terminal output to a file?

The second question is in the body:

How do I save the output of a command to a file?

All the answers posted here address the second question but none address the first question which has a great answer in Unix & Linux:

This answer uses a little known command called script which saves all your shell's output to a text file until you type exit. The command output still appears on your screen but also appears in the text file.

The process is simple. Use:

$ script ~/outputfile.txt
Script started, file is /home/rick/outputfile.txt
$ command1
$ command2
$ command3
$ exit
exit
Script done, file is /home/rick/outputfile.txt

Then look at your recorded output of commands 1, 2 & 3 with:

cat ~/outputfile.txt

This is similar to earlier answer of:

command |& tee ~/outputfile.txt
  • But you don't have to use |& tee ~/outputfile.txt after each commnd.
  • The script command has added benefit (or disadvantage) of reloading ~/.bashrc when it starts.
  • The script command shows the command prompt ($PS1) followed by the command(s) you entered.
  • The script command records all the details in full color.

Send output to clipboard

Many times we want the output to go to the clipboard so we can paste it later. From this answer you can use:

cat ~/.bashrc | xclip -selection clipboard

Now you can use Ctrl+V in almost any application to paste the terminal output into your document. To paste the terminal output in the clipboard back into your terminal use Ctrl+Shift+V instead.

23

You can redirect the command output to a file:

your_command >/path/to/file

To append the command output to a file instead of overwriting it, use:

your_command >>/path/to/file
Eliah Kagan
  • 117,780
chaos
  • 27,506
  • 12
  • 74
  • 77
22

An enhancement to consider -

Various scripts will inject color codes into the output which you may not want cluttering up your log file.

To fix this, you can use the program sed to strip out those codes. Example:

command 2>&1 | sed -r 's/'$(echo -e "\033")'\[[0-9]{1,2}(;([0-9]{1,2})?)?[mK]//g' | tee ~/outputfile.txt
Sean Huber
  • 321
  • 5
  • 7
  • 2
    How to save the output in a way that colours are conserved ? I would like to import the result of a command in libreoffice and keep the colours. – madrang May 12 '15 at 06:36
  • 1
    @madrang: I only read your comment now but you may find this answer useful. – Sylvain Pineau Sep 21 '15 at 10:41
  • Oh, almost exactly what I am looking for. How to print also on screen the output? – Sigur Dec 23 '16 at 22:10
  • 1
    Note that many commands that produce colorized output, such as ls and grep, support --color=auto, which outputs color codes only if standard output is a terminal. – Eliah Kagan Sep 03 '17 at 14:37
15

some_command | tee command.log and some_command > command.log have the issue that they do not save the command output to the command.log file in real-time.

To avoid that issue and save the command output in real-time, you may append unbuffer, which comes with the expect package.


Example:

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

Assuming log.py contains:

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

you can run unbuffer python log.py | tee command.log or unbuffer python log.py > command.log

More information: How can I save a command output to a file in real-time?

  • 1
    They do save the output as they receive it, the problem is that python turns on buffering when the output is not to a TTY. Other options for disabling this in Python: https://stackoverflow.com/q/107705/2072269 – muru Jul 05 '18 at 02:22
  • 1
    Thanks! Spent so long looking for this, and this is exactly what I needed. Works with the stdout from the Google Assistant scripts. – anonymous2 Dec 26 '19 at 02:23
  • You don't need to install expect, stdbuf does the same thing and is generally already there in your distribution. You can "line buffer", which still has the advantage of some buffering and saves time, or completely "unbuffer". – Zakhar Aug 23 '20 at 18:06
11

For cron jobs etc you want to avoid the Bash extensions. The equivalent POSIX sh redirection operators are

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

You'll notice that the POSIX facility is in some sense simpler and more straightforward. The &> syntax was borrowed from csh which should already convince you that it's a bad idea.

tripleee
  • 1,474
3

If you want to output to the file while the command is being run:

script -c ./path/to/executable.bash -f log.txt
Bersan
  • 314
3

Use terminal emulator features

An option not mentioned yet, that can save colours / colors too, is to use a console program — such as Konsole (KDE/Plasma's default terminal emulator) — to save the output.

Konsole

Konsole has: 
File > Save output as... 

the shortcut is Ctrl+Shift+S; it allows the output to be saved as a text file, or as HTML including colors! I'm not sure exactly how much it will save but in my test it only included ~1000, the entire terminal scrollback, (you can increase the buffer by creating a new profile, Profile > New..., and then change the Scrolling settings to capture more; Konsole version 4:21.08.1).

gnome-terminal

gnome-terminal has "copy output as HTML" too, which allows pasting the HTML into a document; it preserves colour but only copies the content of the output currently shown on screen AFAICT.

generically

You can, of course, do a straight drag-select (hold left mouse button whilst dragging) and then copy (ctrl+c, Edit > Copy, or right-mouse-click and choose copy).

others?

Feel free to modify this answer to include other popular terminal apps. My favourite, Yakuake, does not appear to have this feature nor did most of the popular terminals I reviewed, including terminal.app and Hyper.

pbhj
  • 3,231
0

Add this to your .bashrc (based on the script command):

### Logging function:
start_terminal_logging()
{   
    if [ -z "$SCRIPT_LOG_FILE_ACTIVE" ]; then    
        # Log each session to a separate file:
        logdir=~/.terminal_logs
        logfile=$logdir/session_log_$(date +%Y%m%d_%H%M%S)_$$.txt        
        # If no folder exist make one:
        if [ ! -d $logdir ]; then
            mkdir -p $logdir
        fi
        export SCRIPT_LOG_FILE_ACTIVE=$logfile
        # Start logging, a=append, q=quiet:
        script -aq $logfile
        exit
    fi
}
### Start logging:
start_terminal_logging

This will give you a separate file for each session:

session_log_20240107_152455_1955.txt
session_log_20240124_112455_2971.txt
session_log_20240125_092455_6925.txt
session_log_20240125_092750_7048.txt
session_log_20240125_092808_7079.txt
.
.
.

Filename contains a timestamp, so you can easier find what you are looking for.

Danijel
  • 431