38

I am working on automating a maintenance routine that involves starting and stopping a script that is running in a screen session. My approach is to kill the screen session, and then restart it and run the command from within a script using the abilities to both create a screen and pass a command without needing to attach to the screen.

However, I am having difficulties with this. I can create the screen correctly without it attaching using screen -d -m -S screen_name. However, if I run a command based on:

screen -S screen_name-X stuff "command 1"'echo -ne '\015''"command 2"'echo -ne '\015''

with the echo -ne '\015' being wrapped with backticks rather than single quotes. It is to simulate the user pressing the enter key as the commands I use are moving to a directory and executing a script located there. This command works, but only if the screen has been attached to once it has been created. As I am trying to automate the process of creating the screen and running the commands within it I would like to avoid having to attach and detach within a script. I will be trying the suggestion of creating a shell script containing the commands I need to execute within the screen and edit according to my results.

Is there a way to create a screen and run a command within the screen either in one command, or without having to attach to the screen after creating but before execution of the command?

Thanks in advance.

**Update - having tried the suggestion to place the commands I need to execute within a shell script I have been able to successfully create a screen and execute the commands from within the screen, but I am getting the behaviour that when the script stops running the screen closes as well. This shouldnt be a problem as the script is a logging script that should only stop with the knowledge of the sys admin or through the script I am trying to develop, however it would be preferable to have the screen setup in such a way that the screen does not disappear if the script is stopped. Is it possible to achieve this behaviour? **

3
  • 1
    I ran into this same problem and found a solution on superuser.com for anyone else who stumbles upon this problem superuser.com/questions/342463/… Jul 7, 2012 at 1:50
  • To keep the screen open you could use something like: screen bash -c 'echo "test"; /bin/bash'
    – gwyn
    Nov 28, 2012 at 17:30
  • 1
    For your auto-closing issue, you could use a special .screenrc that contains the line zombie kr, which will keep a finished window open, and you can press k to close the winodw, or r to run the command in the window again. I have this for my default .screenrc.
    – Martin C.
    Jul 11, 2014 at 8:56

6 Answers 6

24

I think you may be running into several issues.

If the command finishes before you re-attach, the screen will go away. You can demo this by using:

screen -d -m ls -l

It will run the ls -l command, but screen -list won't show it as the screen process has ended.

I also have no idea what you are trying to do with this \015 stuff. Perhaps updating your question would help, as what I think you're trying to do is run multiple commands in a screen session. This should be as simple as:

screen -d -m bash -c "command1 ; command2 ; command3"

If these are used a lot, perhaps you should make a shell script that runs just these commands, then use a more simple:

screen -d -m /path/to/script.sh
7
  • is there a way to get similar behavior without the screen detaching immediately? Say I want to start an ssh session and then detach right after; screen -d -m ssh will detach at the password prompt before the session is made. Dec 23, 2013 at 7:06
  • This doesn't work for me. Replacing hte "commandN" with several long-running programs results in nothing showing up in screen -list. Also, this doesn't name the screen as the OP is trying to do.
    – Cerin
    Sep 27, 2014 at 3:07
  • I was looking to run a python program using this method. I tried to create a sh script to run it, but did not see the screen in the list. Instead I used screen -d -m python EventGenerator.py, which worked great Nov 27, 2015 at 20:36
  • 1
    That should probably be bash -c "commands" instead of bash "commands" Nov 2, 2016 at 8:04
  • You're right, there has to be -c .
    – Xdg
    Nov 19, 2016 at 7:00
23

Start a detached screen

screen -dmS <screen name>

Execute command in previously created detached screen

screen -S <screen name> -X stuff '<CMD>\n'

Yes you need to type the enter symbol to submit the command or else it will just add the string to the screen.

http://osdir.com/ml/gnu.screen/2003-09/msg00029.html

3
  • 1
    what is 'stuff' ?
    – Nathan G
    Feb 15, 2019 at 8:28
  • 2
    stuff is actually a command that copy-pastes another command into a screen session: stuff [string] Stuff the string string in the input buffer of the current window. This is like the "paste" command but with much less overhead. Without a parameter, screen will prompt for a string to stuff. You cannot paste large buffers with the "stuff" command. It is most useful for key bindings. See also "bindkey". [cited from theterminallife.com/sending-commands-into-a-screen-session/]
    – alisa
    Nov 7, 2019 at 22:42
  • This works really grat, thank you! Oct 22, 2023 at 8:14
4

This did the job for me, without -c wasn't working

screen -d -m bash -c "command1; command2; command3"

2
screen -S test -d -m -- sh -c 'ls; exec $SHELL'
2

I've encountered this problem before, it was a bug with the cygwin implementation.

What I did was create a ".screenrc_detaching" having only the following command

#detach
detach 

and then start screen with

screen -c ~/loginScripts/tempScreenrc/.screenrc_detaching

Then you have your screen session and its already been attached and detached and you're good to pump commands to it.

1

A copy'n'paste way to test previous answers is:

 # No sessions:
screen -ls

 # Returns immediately:
time screen -dmS screen_descritive_session_name  bash -c 'sleep 20; hostname >> /tmp/h'

 # New session present:
screen -ls

 # File with return of command was created :)
sleep 20; cat /tmp/h

The expect result should be similar to:

No Sockets found in /var/run/screen/S-yourusernamehere.

(That means no screen-session was previously created)

real    0m0.002s
user    0m0.000s
sys     0m0.000s

(It's the time spent to create screen and detach from it. Almost instantaneous.)

There is a screen on:
    20318.screen_descritive_session_name    (20/08/2018 16:29:35)   (Detached)
1 Socket in /var/run/screen/S-yourusernamehere.

(This output show screen sessions available. Created on last command.)

sleep 20; cat /tmp/h

(This cat shows the hostname executed inside gnu-screen)

3
  • and what is the result of such tests? Aug 17, 2018 at 19:17
  • You are right, there was no example. I will add. Aug 20, 2018 at 19:43
  • much better! merci! +1 Aug 20, 2018 at 20:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .