How to start vlc-nox via ssh in a Linux server running in text mode? - linux

Background
I have a Linux server running in text mode with no X installed. I intend to show video and image using directfb to the monitor (actually a TV). I have installed vlc-nox and it runs as expected if it is invoked in default console (physical keyboard).
Issue
When running it via SSH, no video is displayed, but audio is okay. The error is as below:
directfb vout display error: Cannot create primary surface
fb vout display error: cannot get terminal mode (Inappropriate ioctl for device)
core video output error: video output creation failed
core decoder error: failed to create video output
fbi's way
I think fbi also facing the same issue, as it would raise an error like below:
ioctl VT_GETSTATE: Inappropriate ioctl for device (not a linux console?)
But, fbi provides a solution for this case: -T -vt <arg> start on virtual console <arg>
So, sudo fbi -T 1 /path/to/image/file would display image as expected.
Question: What's the vlc's way?

I finally have a solution for this, so I post it here in case someone has the same question.
My understanding is that vlc needs to run under a real tty, not a pseudo tty. My solution is composed of two parts.
Part 1: Let vlc run as daemon mode.
Create a user for the daemon and assign audio and video privilege.
#useradd -c "VLC daemon" -d / -G audio,video -M -p \! -r -s /bin/false -u 75 -U vlcd
Run vlc at startup using tty1
I have tried this with unit under ubuntu.
[Unit]
Description=VLC server
After=network.target auditd.service
Conflicts=getty#tty1.service
[Service]
ExecStart=/usr/bin/vlc -I rc --rc-host 127.0.0.1:8080
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
User=vlcd
Type=simple
#StandardError=tty
StandardOutput=tty
StandardInput=tty
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Alias=vlc.service
Please take notic of the Conflicts, ExecStart, StandardInput, and StandardOutput parts.
In Conflicts, it will bypass the default getty service, otherwise it should be disable manually by #systemctrl disable getty#tty1.
In ExecStart, do not use the -d switch, which meaning that it would keep running and occupying VT 1, which is activated by Alt-F1. -rc enables the remote connect interface.
In StandardInput/Output, specify the tty as input and output device.
Part 2: Remote talk with the daemon, to let it play the file.
As --rc-host specify a local port, we need to ssh to the server first. Then, use telnet to interact (add, play, pause) with vlc.
telnet 127.0.0.1 8080
add /path/to/video/file

Related

Linux systemd service file to start and stop a minecraft server

I am trying to run a minecraft server on a remote linux instance.
I would like the instance to start up the server on a screen named serverscreen which is owned by the user named minecraft once the system boots up, and run a stop command to the serverscreen when the instance shuts down. Then, it needs to wait untill the server has stopped before actually shutting down.
I am quite new to linux but I have managed to come up with a few commands that work, but I have issues trying to start and stop the server automatically.
I have tried quite a few things, like creating a .sh script to run on startup with crontab -e #reboot script.sh, or create a file in etc/rc.local with #!/bin/sh sh script.sh, but those methods didn't seem to work properly for me. Also, they do not run un shutdown unfortunately. Therefore, I thought it would be best to create a service file named minecraft.service with the following commands:
[Unit]
Description=Minecraft Server
After=network.target
[Service]
User=minecraft
Nice=5
KillMode=none
SuccessExitStatus=0 1
InaccessibleDirectories=/root /sys /srv /media -/lost+found
NoNewPrivileges=true
WorkingDirectory=/opt/minecraft/server
ReadWriteDirectories=/opt/minecraft/server
#### Command to start the server.
ExecStart=sudo -u minecraft screen -dmS serverscreen java -Xms6G -Xmx6G -jar /opt/minecraft/server/forgeserver.jar nogui
#### Command to stop the server.
ExecStop=sudo -u minecraft screen -S serverscreen -p 0 -X eval "stuff stop^M"
##### Try to wait untill the server has stopped. I am not sure about this line of code since I haven't been able to test it properly.
ExecStop=/bin/bash -c "while ps -p $MAINPID > /dev/null; do /bin/sleep 1; done"
[Install]
WantedBy=multi-user.target
but when running this, it gives me an error saying that I did not provide an absolute path for something.
Could someone help me setup a service file that will boot up the server on a screen named serverscreen for the user minecraft, and run command stop when the instance shuts down after the server has been stopped?
Thanks to #Riz, the service now works as intended by using a bash script in order to run the commands.

How to run an interactive console program like htop directly on tty?

i did make an interesting discovery on my raspberry pi. if I run the following as root:
htop > /dev/tty0
Then the output of htop will be printed directly on screen (hdmi connection)
I would like to run htop as service, but when I do that in a systemd script it says
systemd error opening terminal unknown
How to solve that?
I tried also
cat /dev/null | htop > /dev/tty
Same result...
Set
[Service]
StandardOutput=tty
in the .service file. See systemd.exec(5) for details.

How to run last and print my script output during boot with systemd?

I’m trying to configure my host during deployment process and to give an output to the screen of what my configuration script is doing.
In RHEL6 it was easy i was echoing what I want to screen or used dialog to display the output, and only when my script was done i got the login prompt.
( I used rc3.d or rc5.d folder with script name S99.myscript.sh)
In RHEL7 i can’t mimic this process.
rc.local does not display my output during booting and also its not guaranteed it will run last.
I guess I need to create a systemd service file that will run my script.
But how do I output the result to the screen while booting?
And how do I make sure I will not get the log-in prompt before my script ends?
below service example works like a charm :)
[Unit]
Description=ldt_bootscript1.service
After=network.target
Before=getty#tty1.service
[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/bash /tmp/ldt_scripts/postinstall/rc.firstboot.qas | /usr/bin/dialog --clear --backtitle \"Linux Deployment\" --title \"tests\" --progressbox 20 70 > /dev/console 2>&1"
ExecStartPre=/usr/bin/echo -e \033%G
ExecReload=/bin/kill -HUP $MAINPID
RemainAfterExit=no
WorkingDirectory=/
Environment=TERM=xterm
[Install]
WantedBy=multi-user.target

Programmatically start GPSD daemon in linux

I am doing a project read GPS values output from a GPS dongle and need to
programmatically start the gpsd daemon.
i.e. I need to automate the following command;
sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
I was able to read the coordinates through the code after manually starting the daemon as above. But don't know how to start the daemon through he code.
Since gpsd is a daemon, you can just set the daemon up to be run automatically at startup. How to do this depends on which startup system you have. For example, if you have systemd, you have to write a gpsd.service file, something like this
[Unit]
Description=GPSd daemon service file
[Service]
Type=forking
User=root
Group=dialout
TimeoutStartSec=0
ExecStart=/usr/local/sbin/gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
[Install]
# Grouping mechanism that let systemd start groups of processes up at the same time
WantedBy=multi-user.target
then install it in /lib/systemd/system and finally using the following commands
$ sudo systemctl enable gpsd
$ sudo systemctl start gpsd
the start command is just to run gpsd as systemd daemon without rebooting your system.
for debian its just
dpkg-reconfigure gps

Simple replacement of init to just start console

On a very simple PC, I want to replace Ubuntu 12.04 /sbin/init by the most simple bash script in order to have the very minimum number of running processes. Obviously, no X, no USB, no detection of new hardware, no upgrade, no apt, "nothing", I just need a working console with a DHCP-based Wi-Fi IP address (ssid, passphrase are already stored in /etc/network/interfaces). That's all. Currently, I have tried this in replacement of /sbin/init:
#!/bin/sh
mount -o rw,remount /
mount -t proc none /proc
udevd --daemon
mkdir /run/network
ifup -a &
while [ 1 ]; do
/sbin/getty -8 115200 tty1 vt100
done
It's working as I'm getting an IP address and I can login but:
A) While running shutdown, I get "shutdown: Unable to shutdown system:"
B) control-c is not working in the console
C) After a login, I get: "bash: cannot set terminal process group (-1): Inappropriate ioctl for device"
D) After a login, I get: "bash: no job control in this shell"
Also, I have noticed that all the user-space processes have a "?" in the tty column when running ps avx. How can I fix those problems? I don't want to use upstart in order to really control what is started on the PC and have the very bare minimum.
I ended up using Busybox init. Great tiny init...
You could leverage runlevels and based on your question runlevel 3 is what you want to use.
If you have some services that you do not wish to start, you could turn them off too for that runlevel.
For booting into runlevel 3, you just append the boot argument to the kernel in your boot loader:
<EXISTING_BOOT_CMD> 3
If your distro uses systemd instead of sysvinit, they are instead called as targets. The equivalent of runlevel 3 in systemd is usually named as multi-user.target
The kernel boot argument you would need to pass in this case is systemd.unit=multi-user.target
<EXISTING_BOOT_CMD> systemd.unit=multi-user.target
An alternative, if you do not want to touch the boot loader:
systemctl enable multi-user.target

Resources