5

I am trying to run screen in a special way (I am making an unusual script), and it is not working correctly.


My script:

#!/bin/bash
#startserver


set -m

cd /home/USER/SERVER_FOLDER/

screen -Dm -S SERVER java -Xmx768M -Xms768M -jar ./JARFILE.jar $@ &

PID=$!
echo $PID > ./.mc.pid
(sleep 0.5; sudo /usr/bin/oom-priority $PID) &

(wait $PID; startserver_after) &

screen -r $PID.SERVER

/usr/bin/oom-priority is a coommand I made that sets the priority of the pid to -16.

startserver_after is a command I want to run after java exits.

This isn't working because I cannot resume the screen. Looking at the screen manpage:

-D -m   This also starts screen in "detached" mode, but doesn't fork a new process. The command exits if the session terminates.

That should mean:

  1. The pid of screen should be the same as that of java, however that works.
  2. It is still screen, so I should be able to get to it by screen -r SERVER (but I can't).

When I run the line without the ampersand putting it in the background, it just does nothing until java exits. There is no output.

Coder-256
  • 5,212
  • 2
  • 23
  • 51
  • you're not literally using code `screen -r SERVER` are you? That is not documented use. from `man screen` : ` screen -r [[pid.]tty[.host]]` OR `screen -r sessionowner/[[pid.]tty[.host]]` . Good luck! – shellter Jun 04 '14 at 21:40
  • @shellter aside from $PID, names in all caps are replaced with info that may be confusing/misleading or confidential. But thanks for the info from the manpage. I updated the script. – Coder-256 Jun 04 '14 at 22:56
  • what dose `screen -r SERVER` return? – mofoe Jun 09 '14 at 22:26
  • It' a problem with sessions, you don't have one. eg. login session. Put a `echo $(ps -auxw | grep $PID)` just after the `echo $PID > ./.mc.pid`. The screen isn't there because there is no session to attach to/from. A script is not a session. – Michael Tomkins Jun 10 '14 at 02:02
  • 2
    Also why is there a valid $PID after wait? wait "waits" until the child process **completes** during a fork. So once wait returns there is no PID to return to, because the process has finished. Google "fork and recall processes in bash". – Michael Tomkins Jun 10 '14 at 02:18
  • @shellter - If you name a screen session with `screen -S SomeName`, you can indeed use `screen -r SomeName` or `screen -x SomeName` to reattach to it, regardless of PID/tty; you only need again to specify the PID/tty if you have multiple screens with the same name. See GNU Screen Manual section on the `-S` argument. – DopeGhoti Oct 16 '14 at 18:15
  • What `screen -ls` returns ? – pawel7318 Nov 25 '14 at 18:15
  • The PID of the screen can not be the same as the PID of the java process. No two processes can have the same PID at the same time. – Doncho Gunchev Dec 15 '14 at 04:28
  • @MichaelTomkins in `(wait $PID; startserver_after) &`, the ampersand puts the two commands in the background. A process is forked that runs those two commands one after another detached from bash. In the meantime, `screen -r $PID.SERVER` is run. – Coder-256 Dec 20 '14 at 00:55
  • @Coder256 What are you actually trying to achieve? Maybe there's another way to achieve your goal that is way simpler... – Ralf Apr 18 '15 at 16:19
  • Depending on what you want to achieve , maybe tmux can help. – Prem May 09 '15 at 18:03

1 Answers1

1

If you run screen with -Dm, it will not return to you command line prompt (the "no fork" idea; that's why it doesn't do anything until your java exits if you have no ampersand). If you run it with the -dm, it returns to your command line prompt immediately.

By putting the -Dm in the background, you have caused it to fork and set $! with the PID of your screen process. So that's good.

You are setting the oom-priority of your screen (I doubt you want to do that; I think you were aiming at Java). You can get the pid of your child, like this:

pidchild=$(pgrep -P $PID)

Do you really want to startserver_after after the screen exits? Maybe you want to wait on the child, as well.

Regarding the screen -r at the end: It should work, unless you don't have a tty as stdin of your script, or the java has already exited. Try a ps -p $pidchild immediately after the screen -r and see if the child is still alive. Also run tty as the last command of your script, and make sure it does not return Not a tty.

Mike S
  • 1,235
  • 12
  • 19