0

I've rented a server which I access using the Terminus SSH terminal. I've created a program that has prompts and takes input and works as intended when started normally. But I've created a service to automatically launch it at startup, or when it crashes, but when it's launched from the service it doesn't print any output to the terminal or take any input.

If I leave the Standardinput and Standardoutput blank in the unit file, and use the systemctl status command, I can see the prompts that the program is supposed to print when it's started, but I still cant give it any commands.

I've tried setting the Standardinput and Standardoutput to tty and also tty-force and the TTYPath to /dev/pts/0, because it says thats the tty I'm using. When I do that though it still doesn't give any output or take any input, and also doesn't even give any of the starting output when I use the systemctl status command, same when I use the /dev/console as the TTYPath, which I read is supposed to be the default. So I don't know why it would display those prompts in the systemd status when no standardinput or ouput are set but not display them when they're set to /dev/console, if that's the default.

I've also tried several other ttys like ptyp0, ptyp1, tty0, tty2, and stdin/stdout, but still can't get it to work. Any suggestions?

I've realised there may be issues if it tries to connect to the SSH terminal when I'm not connected to it, if that's the case is there a way to setup a virtual terminal that stays open and use that for the input and output, then just connect to that terminal whenever I log in via SSH?

How would I go about creating the virtual terminal via SSH, and also connecting to it? I've tried chvt 0 and chvt 1 but got "Couldn't get a file descriptor referring to the console.", also tried it using sudo su -, but still the same response.

Here's the unit code

Description= Makes sure server stays running

[Service]
Type=simple

TTYPath=/dev/pts/0
StandardInput=tty
StandardOutput=tty

ExecStart=/usr/lib/jvm/jdk-19/bin/java  -cp /apps/server/lib/*:/apps/server/src packages/Server

Restart=always
RestartSec= 30

[Install]
WantedBy=default.target```
Michael
  • 1
  • 2
  • 1
    If you want to be able to attach and detach from a service at will, you'll want to look into `screen` or its many, varied multiplexers. https://superuser.com/questions/1276775/systemd-service-python-script-inside-screen-on-boot – SHawarden Jan 09 '23 at 03:12
  • SHawarden Thanks, I'll look into screen. And Jaromeda, sorry, I'll break it up into paragraphs now – Michael Jan 09 '23 at 03:31
  • It'd be better if you add to your question the code. By code I mean both the unit file and the code which your systemd unit runs. – Edgar Magallon Jan 09 '23 at 11:14
  • Also,what you want to do (if I understood correctly) about giving input to a script which runs in a systemd service it's not possible. So please update the question and include what the systemd service and the script run. Maybe instead of asking for user input you can create a socket, a named pipe, etc. – Edgar Magallon Jan 09 '23 at 11:20
  • Edgar Magallon, I'll add the untit file but the program it runs is large, it's a server program written in java for a game I'm making. And it has methods for managing it. For instance getting the user list, or removing users. Getting the list of user connections or multiplayer sessions, and their statuses, and how long they've been like that, or any error messages or debug info. And methods to restart or reset any sessions or connection that are frozen up or having issues, without having to restart the whole server program. – Michael Jan 09 '23 at 16:56
  • And I've been leaning towards just writing a quick app for connecting to it via tcp to manage it, instead of using an SSH terminal. I thought about using a second program on the linux server and using it to interact with the program via pipes, but if I'm going to be writing a second app anyway and the original program is already built to recieve tcp connections, might as well just write the program to connect via tcp and be used from my local machine, my phone, and that would allow me more flexibility to have it look and act the way I want, with a custom gui. – Michael Jan 09 '23 at 17:07
  • And I feel I should leave the nature of the original question as it is so that anybody else trying to look to do the same thing can find that it's not possible. Because it took me a while to get that answer, I found somebody else say that but what the other person was trying to do was a little different, so I didn't know if it was the same for what I was trying to do. – Michael Jan 09 '23 at 17:10

1 Answers1

0

You can use screen for this. For example, consider a trivial script ~/noisy.sh that you've made executable (chmod a+x ~/noisy.sh). In your case it would be your long-running complex application.

#!/bin/sh
while :
do
    date
    sleep 5
done

You can push this off into a long-running session with screen like this

screen -S myNoisy -md ~/noisy.sh

The -S <session_name> allows you to identify which screen session is your long running application. I've used myNoisy in the example. As usual you can list sessions with screen ls, attached to this one with screen -r myNoisy, and detach again with Ctrl Ad.

If you want your code to be restarted automatically, use a script like the one I've given as a stand-in example but insert a line between date and sleep 5 with a call to your actual code. Or use screen as the application to start under systemd.

roaima
  • 107,089
  • 14
  • 139
  • 261
  • I think your onto something. But if I wanted it to launch at start up I'd still have to use systemd right. And just set ExecStart to start a screen running that looping script – Michael Jan 09 '23 at 18:42
  • That would work, yes. `screen -md` doesn't need a tty to start (it creates one inside its session) – roaima Jan 09 '23 at 18:50