Linux screen start with command

Send commands to a GNU screen

I can’t even attach the screen. But if i start it separately with screen -S demo then detach and write screen -S demo -X /home/aa/scripts/outputs.sh , nothing different has happened in the screen window

2 Answers 2

If the Screen session isn’t running, you won’t be able to send things to it. Start it first.

Once you’ve got a session, you need to distinguish between Screen commands and keyboard input. screen -X expects a Screen command. The stuff command sends input, and if you want to run that program from a shell prompt, you’ll have to pass a newline as well.

screen -S demo -X stuff '/home/aa/scripts/outputs.sh ' 

Note that this may be the wrong approach. Are you sure you want to type into whatever is active in that session? To direct the input at a particular window, use

screen -S demo -p 1 -X stuff '/home/aa/scripts/outputs.sh ' 

where 1 is the window number (you can use its title instead).

To start a new window in that session, use the screen command instead. (That’s the screen Screen command, not the screen shell command.)

screen -S demo -p 1 -X screen '/home/aa/scripts/outputs.sh' 

Thanks gilles. After I do what you wrote and reattach the screen I see this: /home/aa/scripts/outputs.sh however the script isn’t running until I hit enter. Any suggestion on how to make the script execute as well?

@Kevin: Sorry, I’d misplaced a quote. stuff and the text you want to send need to be in separate arguments. Note that there’s newline inside the quotes.

If you want to send commands that you would normally execute on the shell rather than in a script, you can add the (literal) ^M to the end of the line, e.g.: screen -S demo -p 1 -X stuff ‘echo «hello»^M’ .

screen -S demo -p 1 -X stuff ‘/home/aa/scripts/outputs.sh\n is more readable and works from the command line, as well.

I put this together to capture the output from the commands. It also handles stdin if you want to pipe some input.

function xscreen < # Usage: xscreen command. local SCREEN_NAME=$1 shift # Create screen if it doesn't exist if ! screen -list | grep $SCREEN_NAME >/dev/null ; then screen -dmS $SCREEN_NAME fi # Create I/O pipes local DIR=$( mktemp -d ) local STDIN=$DIR/stdin local STDOUT=$DIR/stdout local STDERR=$DIR/stderr mkfifo $STDIN $STDOUT $STDERR trap 'rm -f $STDIN $STDOUT $STDERR; rmdir $DIR' RETURN # Print output and kill stdin when both pipes are closed < cat $STDERR >&2 & cat $STDOUT & wait ; fuser -s -PIPE -k -w $STDIN ; > & # Start the command (Clear line ^A^K, enter command with redirects, run with ^O) screen -S $SCREEN_NAME -p0 -X stuff "$(echo -ne '\001\013') < $* ; > >(tee $STDOUT) 2> >(tee $STDERR >&2)$(echo -ne '\015')" # Forward stdin cat > $STDIN # Just in case stdin is closed wait > 

Taking it a step further, it can be useful to call this function over ssh:

ssh user@host -n xscreen somename 'echo hello world' 

Maybe combine it with something like ssh user@host «$(typeset -f xscreen); xscreen . » so you don’t have to have the function already defined on the remote host.

Читайте также:  Server configurations in linux

A longer version in a bash script that handles the return status and syntax errors:

#!/bin/bash function usage < echo "$(basename $0) [[user@]server:[port]] command. " >&2 exit 1 > [[ $# -ge 2 ]] || usage SERVER= SERVERPORT="-p 22" SERVERPAT='^(([a-z]+@)?([A-Za-z0-9.]+)):(5+)?$' if [[ "$1" =~ $SERVERPAT ]]; then SERVER="$" [[ -n "$" ]] && SERVERPORT="-p $" shift fi function xscreen < # Usage: xscreen command. local SCREEN_NAME=$1 shift if ! screen -list | grep $SCREEN_NAME >/dev/null ; then echo "Screen $SCREEN_NAME not found." >&2 return 124 # Create screen if it doesn't exist #screen -dmS $SCREEN_NAME fi # Create I/O pipes local DIR=$( mktemp -d ) mkfifo $DIR/stdin $DIR/stdout $DIR/stderr echo 123 > $DIR/status trap 'rm -f $DIR/; rmdir $DIR' RETURN # Forward ^C to screen trap "screen -S $SCREEN_NAME -p0 -X stuff $'\003'" INT # Print output and kill stdin when both pipes are closed < cat $DIR/stderr >&2 & cat $DIR/stdout & wait [[ -e $DIR/stdin ]] && fuser -s -PIPE -k -w $DIR/stdin > & READER_PID=$! # Close all the pipes if the command fails to start (e.g. syntax error) < # Kill the sleep when this subshell is killed. Ugh.. bash. trap 'kill $(jobs -p)' EXIT # Try to write nothing to stdin. This will block until something reads. echo -n >$DIR/stdin & TEST_PID=$! sleep 2.0 # If the write failed and we're not killed, it probably didn't start if [[ -e $DIR/stdin ]] && kill $TEST_PID 2>/dev/null; then echo 'xscreen timeout' >&2 wait $TEST_PID 2>/dev/null # Send ^C to clear any half-written command (e.g. no closing braces) screen -S $SCREEN_NAME -p0 -X stuff $'\003' # Write nothing to output, triggers SIGPIPE echo -n 1> $DIR/stdout 2> $DIR/stderr # Stop stdin by creating a fake reader and sending SIGPIPE cat $DIR/stdin >/dev/null & fuser -s -PIPE -k -w $DIR/stdin fi > & CHECKER_PID=$! # Start the command (Clear line ^A^K, enter command with redirects, run with ^O) screen -S $SCREEN_NAME -p0 -X stuff "$(echo -ne '\001\013') < $* ; echo \$? >$DIR/status ; > >(tee $DIR/stdout) 2> >(tee $DIR/stderr >&2)$(echo -ne '\015')" # Forward stdin cat > $DIR/stdin kill $CHECKER_PID 2>/dev/null && wait $CHECKER_PID 2>/dev/null # Just in case stdin is closed early, wait for output to finish wait $READER_PID 2>/dev/null trap - INT return $(cat $DIR/status) > if [[ -n $SERVER ]]; then ssh $SERVER $SERVERPORT "$(typeset -f xscreen); xscreen $@" RET=$? if [[ $RET == 124 ]]; then echo "To start screen: ssh $SERVER $SERVERPORT \"screen -dmS $1\"" >&2 fi exit $RET else xscreen "$1" "$" fi 

Источник

How to execute a command in screen and detach?

How can I get screen to execute a command and then detach (That is, automatically in a single script without further input beyond initially starting the script)? e.g. I run myscript.sh and it automatically starts a screen session, executes a command, then detaches.

Читайте также:  Сменить ip адрес linux centos

It is important to note that for many of these answers, screen will automatically terminate your screen when the command is done running and the program exits. So, you might think it didn’t work, but you are likely just not seeing it because it terminated. That is why there is a sleep or exec command in answers below, to force screen to not terminate.

8 Answers 8

-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.

Somehow your command wasn’t found, or isn’t working correctly in the automatically-created screen environment. Try just doing screen yourcommand without the -d and -m and see how that goes first.

You’re sort of right. screen terminates when the command finishes, contrary to my expectations. But your answer does work.

You can change that by enabling the zombie option in screen. Put zombie xy in your ~/.screenrc . It should also be possible to enable it for one session only b putting zombie xy in another file and using -c file but for some reason that’s not working when I try it. Or just use sh -c ‘yourcommand;while :;do sleep 9999; done’

@AlanCurry, Nope, this doesn’t work for me either, even though the command runs perfectly (and takes several hours) when run in a screen manually.

To run a single command in screen and detach, you may try:

To run multiple commands, try:

screen -dm bash -c "sleep 10; myscript.sh" 

Please note that when a program terminates, screen (per default) kills the window that contained it.

If you don’t want your session to get killed after script is finished, add exec sh at the end, e.g.:

screen -dm bash -c 'sleep 5; exec sh' 

To list all your sessions, try:

This worked for me on Ubuntu 16.04. In addition to name your session so you can return to it later, add -S sessionname : screen -dmS MyLongRunningScript bash -c «. » .

@kenorb, the problem is that it only worked with single quotes. Let’s say: ‘for k in `seq $i $j`; do echo $k; done’ , where $i and $j are from the parent script.

This is a robust answer. I needed bash -c . I can only assume that when I called screen -dm head foo > bar it wrote screen -dm head foo to bar . screen -dm bash -c «head foo > bar» fixed that.

In order to start new session in background with name ‘sleepy’

screen -S sleepy -dm sleep 60 

In order to kill ‘sleepy’ session

Читайте также:  Как определить домен linux

@Toolkit The issue is that you have the command in quotes and so it was treated as one large command. Obviously we can’t take it out of quotes because of the semicolon. To solve this, execute the command like so: screen -S sleepy -dm bash -c «cd myfolder;sleep 60»

screen -dmS screen_session_name bash -c 'echo "doing stuff"; exec bash' 

it happen to me when I pressed control c (sig int) to exit my program. it exits all the way from all bash. so I found this to catch SIGINT. and prevent exit from last bash. (need to type exit to exit)

screen -dmS "screenNameHere" bash -c "trap 'echo gotsigint' INT; cd /mydir ; my_command_here; bash" example: screen -dmS "status_updates" bash -c "trap 'echo gotsigint' INT; cd /opt/status_update ; forever index.js ; bash" 

I find it useful to use cron to run nodejs programs on startup. and to run the screen at boot time. in cron there are special events syntax @reboot event

to edit cron, execute: crontab -e then type @reboot screen -dmS "screenNameHere" bash -c "trap 'echo gotsigint' INT; cd /mydir ; my_command_here; bash" 

Источник

How to create a screen executing given command?

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" 

7 Answers 7

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.

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.

Источник

Оцените статью
Adblock
detector