0

I have following code to execute some commands on a virtue screen:

screen -R << EOF
    cd /home/users/devops_tester/apps/Selenium-Webdriver
    export DISPLAY=:99
    npm start
EOF

It gives me an error:

Must be connected to a terminal.

How can I solve it?

I found this related topics but I am not using ssh:

How can I launch a screen session with a command over ssh on a remote server from my desktop?

This is the screen app:

https://packages.ubuntu.com/trusty/screen

3 Answers 3

3

First of all -R means you are attempting to resume an existing screen session that probably already runs something. In that case you can't just push your shell commands into it and hope they will be executed. What if the resumed screen session had for example an editor running? So, don't use -R when you want to specify a command to run.

The other problem is that once you use input redirection through << __EOF__ the called program runs without a tty, i.e. without an interactive terminal. That can be easily demonstrated here:

$ tty
/dev/pts/0

$ tty << __EOF__
__EOF__
not a tty

Fortunately for you screen has a support for running custom commands upon launch. It's as simple as screen command args (notice no -R in after screen).

In your case you'll have to pass all your commands as arguments to /bin/sh because screen won't run multiple shell commands for you. Something like this should work:

$ screen /bin/sh -cx "cd /home/users/devops_tester/apps/Selenium-Webdriver; export DISPLAY=:99; npm start"

It will spawn a new screen session and run your commands. The -x makes shell print the commands it runs for your reference. It's optional, you can remove it.

You can also run the above in an immediately detached screen session and re-attach to it later:

$ screen -d -m /bin/sh -cx "cd /home/...; export ...; npm start"
# runs the commands in screen but returns immediately

That's useful if you want to run the commands during system startup for instance.

And of course you can re-attach the above session to see what's going on there.

$ screen -R    # re-attach to the above screen session

Last but not least - instead of passing all your commands as arguments to /bin/sh it may be easier to create a little 3-liner shell script, make it executable and run that with a simple call:

$ screen /path/to/the-script
2
  • Thank you! It works well. But, I got some issue when I run the command through jenkins. The jenkins process keep running after showing [screeen is terminating]. How can I exit screen process properly?
    – zhangjinzhou
    Commented Jul 11, 2017 at 23:37
  • 1
    @zhangjinzhou sorry I don't know much about Jenkins. Feel free to open another StackExchange question and describe the problem there, perhaps linking to this one for reference.
    – MLu
    Commented Jul 12, 2017 at 0:01
0

You can also use the screen 'stuff' command to inject commandlines into the shell contained in a running screen session.

NL=$(echo -ne '\015')
screen -S YOURSCREEN -dm
#
# Wait a sec for screen to get going...
sleep 1
screen -S YOURSCREEN -p 0 -x stuff "cd /home/users/devops_tester/apps/Selenium-Webdriver${NL}"
screen -S YOURSCREEN -p 0 -x stuff "export DISPLAY=:99${NL}"
screen -S YOURSCREEN -p 0 -x stuff "npm start${NL}"

I use this technique to launch long running interactive processes from startup at boot time, in systemd or init.d

0

The example below runs the code when the script is executed or the same code in a screen session with ./my_script.sh -s.

# contents of my_script.sh:

if [ "$1" == "-s" ]; then
    screen "$0"
else
    # code
fi

You must log in to answer this question.