Run (GNU) Screen from script

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

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.


is using byobu an option ?


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!