41

i'm fairly new in *nix. Is there a way to create a screen, which will immediately execute a given command sequence (with their own arguments)? Two hours of googling yields nothing - perhaps because I can't clearly state the question.

I hope for something like

screen -dmS new_screen exec "cd /dir && java -version"

I am using screen v4.00.03 and CentOS 5.5 (kernel ver. 2.6.18-194.26.1.el5.028stab079.2)

Alex Abdugafarov
  • 6,112
  • 7
  • 35
  • 59

7 Answers7

52

You create a screen with a name and in detached mode:

screen -S "mylittlescreen" -d -m

Then you send the command to be executed on your screen:

screen -r "mylittlescreen" -X stuff $'ls\n'

The stuff command is to send keystrokes inside the screen. The $ before the string command is to make the shell parse the \n inside the quotes, and the newline is required to execute the command (like when you press enter).

This is working for me on this screen version:

$ screen -v

Screen version 4.00.03jw4 (FAU) 2-May-06

Please see man screen for details about the commands.

kR105
  • 864
  • 9
  • 15
41

The problem is that using the 'exec' screen command does not start a shell. 'cd' is a shell builtin, so you need a shell for it. Also, you need a shell that remains running so that screen does not terminate.

You can use the -X option to screen to send commands to a running screen session, and the 'stuff' command to send keystrokes to the current window. Try this:

screen -dmS new_screen sh
screen -S new_screen -X stuff "cd /dir
"
screen -S new_screen -X stuff "java -version
"

Yes, you need to put the quotes on the next line in order for the commands to be executed.

mloar
  • 1,514
  • 11
  • 11
8

screen -dmS screen_name bash -c 'sleep 100'

This will create new screen named screen_name. And inside the screen it will sleep for 100 seconds.

Note that if you type some command in place of sleep 100 which terminates immediately upon execution, the screen will terminate as well. So you wont be able to see the screen you just created

Tushar Goswami
  • 753
  • 1
  • 8
  • 19
2

I wanted to launch remote screens from within a bash script with some variables defined inside the bash script and available inside screen. So what worked for me was

#!/bin/bash
SOMEVAR1="test2"
# quit existing if there is one running already, be careful
screen -D -RR test1 -X quit || true
screen -dmS test1
screen -r test1 -p 0 -X stuff $"echo ${SOMEVAR1} ^M"

Where the return character, ^M, you need to enter using vim as

i CTRL-V ENTER ESCAPE
jsh
  • 261
  • 1
  • 12
2

Another approach

First line cd to the your directory. Second line start a new screen session named new_screen with bash. Third line executing java -version

cd /dir
screen -dmS new_screen bash
screen -S new_screen -p 0 -X exec java -version
Dilushan
  • 143
  • 1
  • 10
1

I think that you can use this

function exec_in_screen() {
  name=$1
  command=$2
  screen -dmS $name sh; screen -S $name -X stuff "$command\n";
} 

Then...

exec_in_screen "test" "ls"

The_Black_Smurf
  • 5,178
  • 14
  • 52
  • 78
Pedro Rodrigues
  • 1,662
  • 15
  • 19
-3

Yes, what you want is the "stuff" command

for example

screen -dmS new_screen -X stuff "cd /dir && java -version

"

the second quote is on the next line so that it executes when sent

dukevin
  • 22,384
  • 36
  • 82
  • 111