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

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:


migrated from serverfault.com Aug 1 '17 at 4:07

This question came from our site for system and network administrators.


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

$ tty << __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
  • 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 Jul 11 '17 at 23:37
  • @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 Jul 12 '17 at 0:01

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy