189

I need to save the whole output of Screen to a file to check later all the content.

The reason is that I'm dumping a flash memory through a serial port, using Screen to interface with it. I would like to save it to a file to check memory structure.

I've tried:

screen /dev/ttyUSB0 115200 >> foo.txt
screen /dev/ttyUSB0 115200 | tee foo.txt

And I've also tried to use bufferfile from screen, but I don't understand how to use it.

Is there an easy way?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edoardoo
  • 2,739
  • 4
  • 18
  • 27
  • The production setting I am using has multiple instances of screen. The one whose output I need has line as 'pts/10'. Hence what should I do to obtain its output to a file? – Sid Sep 08 '16 at 10:54

12 Answers12

187

There is a command line option for logging. The output is saved to screenlog.n file, where n is a number of the screen. From man pages of screen:

‘-L’ Tell screen to turn on automatic output logging for the windows.

Fergie
  • 1,913
  • 1
  • 12
  • 10
  • 11
    Thanks. Is there is a way to output what screen already has in its output buffer? E.g. I forgot to enable logging, but output is available in the scroll screen buffer - how to write that to a file? – Tagar Jun 29 '15 at 22:32
  • 73
    Just googled a bit more.. Here's answer for my repvious comment - http://stackoverflow.com/questions/4807474/copying-gnu-screen-scrollback-buffer-to-file-extended-hardcopy Ctrl+A and : to get to command mode, then hardcopy -h in case somebody elsee will need this. – Tagar Jun 29 '15 at 22:34
  • 6
    Log file will be created in the same directory in which you executed screen. – lepe Feb 09 '16 at 04:32
  • 2
    Yesterday I did a "screen -L", disconnected my SSH session, logged in again today and reattached using "screen -r" (I only had one), exited, and did a `find / -name "screen*log"` which found nothing. – pacoverflow Apr 15 '16 at 14:42
  • 3
    related: [Is it possible to name the screen logfile from the L flag?](http://stackoverflow.com/questions/15026184/is-it-possible-to-name-the-screen-logfile-from-the-l-flag) – lepe Jun 01 '16 at 03:44
  • I use -r to reconnect to my screen instance. Hence when I try to do screen -rL instance, it didn't log the output. Also, my screen is multiple instance but I want output of only one instance, how to achieve this? – Sid Sep 08 '16 at 10:56
  • Is there way to specify the logfile that should be augmented? – Necktwi Feb 13 '17 at 21:29
  • This did nothing for me – Ruan Carlos Aug 21 '18 at 16:33
  • @pacoverflow It appears that `screen` deletes the log file upon exiting. If you want to save the logfile, copy it before you exit `screen` (detaching and reattaching should not clear the logfile) – emunsing Dec 22 '18 at 02:27
137

You can also use Ctrl + A, H to save loggings into a screenlog.n file.

And one more Ctrl + A, H to turn it off.

Ctrl + A, H: Begins/ends logging of the current window to the file "screenlog.n".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
NeliJ
  • 1,391
  • 1
  • 8
  • 5
  • 7
    +1. If the log can’t be created, then try changing the screen window’s working directory: Ctrl-`a` + `:` and type for example `chdir /home/foobar/baz` – Chriki Jan 23 '15 at 12:11
  • 2
    C-a + H just switches screen windows for me. Nothing to do with a log file! – aaa90210 Mar 14 '17 at 00:22
  • 6
    @aaa90210 It's ctrl-a followed by a separate press of h for a hardcopy. ctrl-a followed by a separate press of shift-h starts a complete log file. – James Mar 27 '18 at 09:47
  • 1
    Looking for the screenlog.0 file created by Ctrl-a H? https://unix.stackexchange.com/questions/198881/where-can-i-find-the-screenlog-0-file – straville Jan 04 '19 at 14:54
59

The following command works for Screen version 4.06.02:

screen -L -Logfile Log_file_name_of_your_choice command_to_be_executed

From the man page of Screen:

-Logfile file : By default logfile name is "screenlog.0".
                You can set new logfile name with the "-Logfile" option.

You can check the existing version of Screen using screen -version. You can download and install the latest Screen version from https://www.gnu.org/software/screen/.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nikhil
  • 1,054
  • 9
  • 9
  • Also you can leave the command_to_be_executed as blank and enter a series of long running jobs – devssh May 14 '19 at 11:00
  • 1
    Remember to have write permissions to screen's working directory, because otherwise it fails silently (simply not logging without any warning) – okrutny Mar 10 '20 at 15:03
26

The selected answer doesn't work quite well with multiple sessions and doesn't allow to specify a custom log file name.

For multiple screen sessions, this is my formula:

  1. Create a configuration file for each process:

    logfile test.log
    logfile flush 1
    log on
    logtstamp after 1
    logtstamp string "[ %t: %Y-%m-%d %c:%s ]\012"
    logtstamp on
    

    If you want to do it "on the fly", you can change logfile automatically. \012 means "new line", as using \n will print it on the log file: source.

  2. Start your command with the "-c" and "-L" flags:

    screen -c ./test.conf -dmSL 'Test' ./test.pl
    

    That's it. You will see "test.log" after the first flush:

    ...
    6 Something is happening...
    [ test.pl: 2016-06-01 13:02:53 ]
    7 Something else...
    [ test.pl: 2016-06-01 13:02:54 ]
    8 Nothing here
    [ test.pl: 2016-06-01 13:02:55 ]
    9 Something is happening...
    [ test.pl: 2016-06-01 13:02:56 ]
    10 Something else...
    [ test.pl: 2016-06-01 13:02:57 ]
    11 Nothing here
    [ test.pl: 2016-06-01 13:02:58 ]
    ...
    

I found that "-L" is still required even when "log on" is on the configuration file.

I couldn't find a list of the time format variables (like %m) used by screen. If you have a link of those formats, please post it bellow.

Extra

In case you want to do it "on the fly", you can use this script:

#!/bin/bash
if [[ $2 == "" ]]; then
    echo "Usage: $0 name command";
    exit 1;
fi
name=$1
command=$2
path="/var/log";
config="logfile ${path}/${name}.log
logfile flush 1
log on
logtstamp after 1
logtstamp string \"[ %t: %Y-%m-%d %c:%s ]\012\"
logtstamp on";
echo "$config" > /tmp/log.conf
screen -c /tmp/log.conf -dmSL "$name" $command
rm /tmp/log.conf

To use it, save it (screen.sh) and set +x permissions:

./screen.sh TEST ./test.pl

... and will execute ./test.pl and create a log file in /var/log/TEST.log

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lepe
  • 24,677
  • 9
  • 99
  • 108
  • 2
    Thank you - the `on-the-fly` part is super useful. – Ram RS Oct 12 '16 at 21:57
  • 1
    Following up, a screen run overnight with a config file created and deleted on the fly errored out on a `screen -r` with `"Unable to open "/tmp/log.conf"`. Also, the screen went from `[detached]` state to non-existent. What could have been the problem? – Ram RS Oct 13 '16 at 14:26
  • 1
    What does your command do? screen will recreate the log file when missing, so I'm guessing /tmp/ run out of space or had some other OS related problem? I use this approach in several servers which run indefinitely and so far I haven't seen such situation in at least 1 year. If you want we can start a chat and I can help you to debug your problem. – lepe Oct 14 '16 at 06:35
  • It was over an SSH and disconnected so I had to log in again. Could that have anything to do with this? For the moment I save the conf file to the `pwd` as well, so it's working OK. – Ram RS Oct 14 '16 at 11:24
  • My command runs a long pipeline which uses our cluster to run a whole lot of jobs, but I don't think that had anything to do with this. – Ram RS Oct 14 '16 at 14:52
  • You said before, the screen went from [detached] to non-existent. The only situation I know for that to happen is that your process exited (could be a crash, fatal error, connection lost, etc). Better to check logs and see if there is any clue in them. The only solution I can think of, is to be sure that no matter what, the child process would never exit (wrap it in a infinite-loop script). – lepe Oct 17 '16 at 01:43
  • Hmmm, the process did error out. However, I rarely start a `screen` detached. I usually give it a `-c`, a `-L` and a `-S` then run commands inside the screen so it shouldn't terminate no matter what happens to the child process, right? – Ram RS Oct 17 '16 at 14:49
  • 1
    I think you are right, it should no terminate the screen if you are running the process that way, which is the same as executing: `screen bash`. If any other process is killing your screen, it should be listed as 'dead', but no disappear. I'm not sure what can it be. – lepe Oct 18 '16 at 01:03
  • Never mind, I just save the conf file as `$(pwd)/${name}.screenrc` and the log file as `$(pwd)/${name}.screenlog` and that works fine (I think) although I see a brief error flash - I'll try and catch that the next time I start a screen. – Ram RS Oct 18 '16 at 10:57
  • It just happened again! If I try and attach a detached `screen` whose `screenrc` file has been moved, the screen just terminates. This one terminated in the middle of a process :( – Ram RS Oct 18 '16 at 19:47
  • `'$name'` should probably be quoted in double quotes: `"$name"` – qräbnö Jan 21 '19 at 12:39
  • 1
    @qräbnö : Nice catch! All this time and I didn't notice it. I updated the answer accordingly. – lepe Jan 25 '19 at 03:56
  • This made me realize -- somewhere between screen versions `4.03.01` and `4.06.02`, the argument order matters. Whereas before I had `-dmLS` as the flags, that no longer worked on `4.06.02`. Changing it to `-dmSL` as per this example, it works like a charm again. – Mave Jul 21 '21 at 09:52
21

The existing screen log can be saved by:

Ctrl+A : hardcopy -h filename

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ratan Raj
  • 349
  • 2
  • 4
18

For the Mac terminal:

script -a -t 0 out.txt screen /dev/ttyUSB0 115200

Details

  • script: A built-in application to "make a typescript of terminal session"
  • -a: Append to output file
  • -t 0: Time between writing to output file is 0 seconds, so out.txt is updated for every new character
  • out.txt: Is just the output file name
  • screen /dev/ttyUSB0 115200: Command from question for connecting to an external device

You can then use tail to see that the file is updating.

tail -100 out.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ryan
  • 841
  • 8
  • 12
  • 1
    This did not work for me on a Mac. The log file shows the script starting the common and the command ending, but not the data received from the screen command. – David Sep 09 '17 at 03:25
13

Ctrl+A then Shift+H works for me. You can view the file screenlog.0 while the program is still running.

muru
  • 4,723
  • 1
  • 34
  • 78
jaggedsoft
  • 3,858
  • 2
  • 33
  • 41
10

A different answer if you need to save the output of your whole scrollback buffer from an already actively running screen:

Ctrl-a [ g SPACE G $ >.

This will save your whole buffer to /tmp/screen-exchange

rkelleycook
  • 101
  • 1
  • 2
  • 3
    This post[1] offers a simpler solution: `Ctrl + a`, then `:` to get to command mode, and then `hardcopy -h ` 1. https://stackoverflow.com/a/6604296/1734789 – Tarjei Huse Oct 26 '20 at 19:47
8

Here's a trick: wrap it in sh -c!

screen sh -c './some-script 2>&1 | tee mylog.log'

Where 2>&1 redirects stderr to stdout so tee can catch and log error messages.

rkok
  • 1,047
  • 14
  • 17
7

The 'script' command under Unix should do the trick. Just run it at the start of your new console and you should be good.

Ruben
  • 1,427
  • 3
  • 17
  • 25
  • great! where does it print it? – Edoardoo Jan 08 '13 at 14:02
  • It should just writes to a file. Command is a bit messy but I think this might solve that a bit: http://linux.byexamples.com/archives/279/record-the-terminal-session-and-replay-later/ – Ruben Jan 08 '13 at 22:32
6

The following might be useful (tested on: Linux/Ubuntu 12.04 (Precise Pangolin)):

cat /dev/ttyUSB0

Using the above, you can then do all the re-directions that you need. For example, to dump output to your console while saving to your file, you'd do:

cat /dev/ttyUSB0 | tee console.log
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Keo Malope
  • 1,015
  • 12
  • 19
  • This one worked for me perfectly. I'm logging serial monitor output from an Arduino data capture session. – Ian Pitts Oct 21 '17 at 15:43
1

It cost me a lot to find a clean solution. Although previous replies are fine, I found out this to be more direct.

This command will wait 5 seconds to write the output to a file. The 'sudo' part depends of your environment.

screen -dm bash -c 'sleep 5;echo "done" | sudo tee ./test.txt'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alberto Soto
  • 111
  • 3