13

I would like to launch some application inside screen session but from a script.
Without script I would just launch screen, then open N windows with crtl-a-c and execute programs in each windows.

I tried the following

screen -d -m -S test
screen -S test -X exec tail -f /var/log/messages
screen -S test -X screen
screen -S test -X exec tail -f /var/log/xinetd.log

But when I attach the session tail is not running. If I attach the session just after screen -d -m -S startup and run screen -S startup -X exec tail -f /var/log/messages from another terminal it works.

Did I miss something ?

Edit after AlexD answer:

An half working solution is

screen -d -m -S test tail -f /var/log/messages
screen -S test -X screen tail -f /var/log/xinetd.log

Chaining screen command (the one after -X) with the command is working while exec is not probably because exec expect a current window to be defined while there is no current one when screen is detached. Thanks to AlexD for this tips.

But there is a weird side effect : when the program stop (if you attach the screen session and crtl-c the tail, or kill tail) the screen window will close.
So the behavior is not the same as Crtl-A c and run the command
Another side effect is that you can't chain 2 commands

2
  • screen always terminates when the command with which is was launched ends - it's a normal feature of the tool :) ..so if you run screen top, when you quit top, screen will quit, too
    – warren
    Jul 1, 2010 at 12:51
  • Yes I now that, this is why I tried launching screen as deamon then use exec then use the screen command to open a new window (lauching a shell). I also tried tu prepend bash between exec and tail or between screen and tell but neither are working
    – radius
    Jul 1, 2010 at 14:01

4 Answers 4

18
+100

The screen -S test -X screen command command is what you need to add windows to your daemon session, but not for the reasons you give. It works because -X takes a screen command and not a shell command, and the screen command to create a window is called, confusingly, screen. There is no exec screen command. There is no chaining either, unless you build your command using shell scripting (like this: screen -S script -X screen sh -c 'command1; command2;').

Calling screen -S test -X screen with no command is useless because the default command is a shell, and once you have spawned a shell, you don't have a noninteractive (and non-devious) way to run commands inside that shell. It is better to run the command by itself, without an interactive shell. A side effect is that when the command exits, the screen window doesn't have a child any more, and will close.

Now, you can ask screen to hold the window open anyway, after the command has quit. Use the zombie screen command to enable that. Your sequence looks like:

screen -d -m -S script
screen -S script -X zombie qr
screen -S script -X screen tail -f /var/log/messages
screen -S script -X screen tail -f /var/log/xinetd.log

To reattach interactively:

screen -S script -r

And finally, you can rewrite these -X commands as a screenrc script instead.

Screenrc:

zombie qr
screen tail -f /var/log/messages
screen tail -f /var/log/xinetd.log

Script:

screen -d -m -S script -c screenrc
2
  • Yes I know that -X is taking a screen command, that what I mean when I said "Chaining screen command (the one after -X)" (Ok it's not clear at all) but there is a screen exec command, look the man page, but as you said there is no way to got it work as wanted in noninteractive mode. Anyway with AlexD solution and you zombie command add I got what I want ! Thank you
    – radius
    Jul 1, 2010 at 23:37
  • @Tobu: +200 for mentioning zombies! I'd have ultimately never noticed it in that dreadful manual!
    – vines
    Dec 13, 2011 at 23:06
7

If you want same effect as Ctrl-A c then you should use screen instead of exec:

screen -S test -X screen tail -f /var/log/messages
screen -S test -X screen
screen -S test -X screen tail -f /var/log/xinetd.log

Also, you could move your commands above to $HOME/.screenrc-younameit file (without screen -S test -X prefix) and launch screen -c $HOME/.screenrc-younameit when you want to create specific screen session.

2
  • The Ctrl-A c is in my 3rd line, I guess exec is not working because exec run the command in the current windows which might not be defined when screen is detached. Your workaround chaining screen and the command is nice, I should have tried it ! I will add an answer to myself because your answer lacks the session creation and has a useless line (2nd one, skipping 1 window)
    – radius
    Jun 29, 2010 at 11:07
  • In fact it's not working as expected, the windows close as soon as the program stops. if you do screen -S test -X screen ls, the window will close and you will never see the result
    – radius
    Jun 29, 2010 at 11:21
1

is using byobu an option ?

1
  • I have just try it, I don't see how it could help but if you have a working solution with byobu it could be ok, I rather prefer a screen only solution but using an add on is better than having no solution !
    – radius
    Jul 1, 2010 at 13:54
1

I was doing to same thing tonight, I wanted to open screen with several files pre-opened. It took me a while to figure all of this out but I finally come up with the following which seems to work pretty nicely:


#1/bin/sh 
screen -d -m -S CS140 
screen -S CS140 -X screen -t thread.c 
screen -p 1 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.c\015"'
screen -S CS140 -X screen -t thread.h 
screen -p 2 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.h\015"'
screen -S CS140 -X screen -t palloc.c 
screen -p 3 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/palloc.c\015"'
screen -S CS140 -X screen -t intr-stubs.h 
screen -p 4 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/intr-stubs.h\015"'
screen -S CS140 -X screen -t pagedir.c 
screen -p 5 -S CS140 -X eval 'stuff "vim cs140-ps2/src/userprog/pagedir.c\015"'
screen -r -d CS140 

This will create six different screens, with screens 1-5 having opened various files. I don't know all the specifics but 'stuff' essentially tells screen the following quoted text is not a screen command. The 'eval' then evlautes everything contained in the quotes. Without this the screen -p 4 -S CS140 -X stuff "vim cs140-ps2/src/threads/intr-stubs.h\015" simply pipes the quoted text without executing it. Eval will read '\015' as a newline and thus execute the preceding text.

In terms of other details, screen -p 1 -S CS140 -X CMD tells the shell to send the 'CMD' to the first window of the screen session named 'CS140'.

Hope that helps!

You must log in to answer this question.

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