5

Running a command in a screen and detaching is quite simple.

screen -S test -d -m echo "output of command that runs forever"

However I would also like to pipe all the output to a file for logging, how can run the following in a screen and detach.

echo "output of command that runs forever" &> output.log

Edit:

Just to clarify, I need this for a script so simple starting a screen and doing running the command and detaching is not an option.

3 Answers 3

5

You can wrap your command in an extra bash (or your actual shell) call and make redirection there:

$ screen -dm bash -c 'echo hello > ./out'
$ cat ./out
hello

From the man screen:

-d -m Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.

Naming a session

It may be suitable to name your background jobs to disambiguate them in the screen -ls and to attach if neccessary:

$ screen -S mysession -dm sleep 20
$ screen -ls
8431.mysession  (10/04/2021 12:47:58 PM)    (Detached)

# attach
$ screen -r mysession

How to pass arguments

Parameterization may be a hassle though. The arguments being passed are fed into bash starting with $0 -- note the ignore_me_arg:

# note the outer-most quotes to be single -- we don't want them to
# be expanded on the caller's side, but on the callee's one

$ screen -dm bash -c 'echo $1 > ./out' ignore_me_arg hello
$ cat ./out
hello

As a final example, let's say you have a program super_script that does some stuff and prints all its arguments to stdout (as echo would do). You want to call it inside screen, make a redirection, and do all that jazz with different sets of arguments. Then this should do:

$ screen -dm bash -c 'super_script "$@"  > ./out.1' arg0 arg1
$ screen -dm bash -c 'super_script "$@"  > ./out.2' arg0 arg1 arg2
... wait for screen's to finish
$ cat out.1
arg1
$ cat out.2
arg1
arg2
4

screen -dmS workspace; screen -S workspace -X stuff $'ps aux > output-x\n'

I first create a detached session with the -d switch, I called my session workspace. I then send my command to the same session with -X stuff, I am using $'', but you could also use double quotes, but have to do a control M instead of a \n, which I don't like so I normally use the method I described above.

After this piece of code runs, you will find the output-x with the list of processes, and also if you do a:

screen -ls

you will see the session has been detached.

Since you said you are going to be running a script. You might want to have your script search for a detached session (I am using workspace), and if it exists send commands to that pre-existing session, instead of making a new session every time "screen -dmS sessionName" is ran, example is below:

    #!/bin/bash
    if ! ( screen -ls | grep workspace > /dev/null); then
       screen -dmS workspace;
    fi
    screen -S workspace -X stuff $'ps aux > output-x\n'
6
  • Thank you very much, this helped. On slower vms I did have to add a sleep between the two commands for it to work reliably. Jan 29, 2016 at 15:15
  • does this work if we wanted to monitor serial port, for e.g. screen /dev/ttyUSB0?
    – deostroll
    Jul 28, 2019 at 2:36
  • Which purpose of the stuff in the command? I tried to execute the command exactly and nothing happened. No log file was created and when I activated workspace there was no any output there. I tried it in macOS's Terminal.
    – dmitry1100
    Apr 21, 2020 at 7:37
  • @C0DEF52 it is an input buffer of a window. You can search for that term in the manual page located here. Were you running the script? Or were you just running that one line. That one line connects to a screen session called workspace, and then stuffs a string as input to that window like you typed it, when you do a screen -ls you should see the session called workspace, and when you attach to that window you will see the input was indeed sent to a window, and there should be an output-x file created with the process list in it.
    – NiteRain
    Apr 21, 2020 at 12:33
  • @NiteRain I tried one line and script in default macOS Terminal app. Here I recorded a video how I tried a single line variant: youtu.be/gpQHP3fZ8T4
    – dmitry1100
    Apr 22, 2020 at 23:39
0

You can use the disown or nohup

usage: How to monitor WGET download progress after closing SSH session

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.