nohup SBCL ubuntu couldn't read from standard input - linux

On Ubuntu I compiled sbcl 1.0.35 with threading. I can happily use sbcl from the command line and my hunchentoot website works with threading but when I logout it's gone. When I attempt to nohup sbcl
nohup ./src/runtime/sbcl --core output/sbcl.core
I get
(SB-IMPL::SIMPLE-STREAM-PERROR "couldn't read from ~S" # 9)
I've attempted various combinations of redirecting the standard input to /dev/null or a file and using the script command line option but I don't quite get what is going on.
How do I start sbcl from the command line on linux with nohup and keep my repl(website) running?

RESTAS web-framework ("REST Application Server") by Andrey Moskvitin contains code to properly daemonize SBCL instance. See http://github.com/archimag/restas/blob/master/contrib/restas-daemon.lisp. You can easily rip off RESTAS-specific parts.

You could start SBCL in Gnu Screen and then detach from the session.
This also gives you the possibility to reattach to your REPL later.

Dmity-vk sent me on the right track, thank you. SBCL tries to start a repl when you start it up, and reads from the standard in. When you use nohup the standard in is redirected and cannot be read. SBCL then drops to the debugger which tries to read from standard in ... hence the endless loop. The --script tag comes close to solving this except that it has a (quit) once the script has been read. So I put an endless loop in my script and voila.
so on an ubuntu server with sbcl this should let you start a hunchentoot server
sudo nohup ./run-sbcl.sh --script foo.lisp > /dev/null 2> /dev/null &
where foo.lisp has as its last lines something like
(defvar *alive* t)
(loop (sleep 1000) (if (not *alive*) (quit)))

Related

Linux shell wrap a program's stdin and stdout using pipes

So, I have this interactive program that is running on an embedded linux ARM platform with no screen and that I cannot modify. To interact with it I have to ssh into the embedded linux distro, and run the program which is some sort of custom command line with builtin commands, and it does not exit, only SIGINT will quit the program.
I'm trying to automate it by letting it run in the background and communicate with it using pipes by sending SSH commands like this ssh user#host echo "command" > stdinpipe. This part works, I've been provided with an example like this in a shell script (I cannot use bash, I only have ash installed on the machine) :
#!/bin/sh
mkfifo somePipe
/proc/<PID>/exe < somePipe 2>&1 &
I can now easily command the program by writing to the pipe like
echo "command" > somePipe
and it outputs everything inside the terminal. The problem is that while it works if I have an SSH session open, it won't if I only send commands one by one as I said earlier (I'm using paramiko in python with the exec_command() method, just in case, but I don't think that is relevant, I could use invoke_session() but I don't want to have to deal with recv())
So I figured out I'd redirect the output of the program to a pipe. That's where problems arise. My first attempt was this one (please ignore the fact that everything is run as root and stored in the root home folder, that's how I got it and I don't have the time to make it cleaner now, plus I'm not the one managing the software) :
cd /root/binary
mkfifo outpipe
mkfifo inpipe
./command_bin &
# find PID automatically
command_pid=$(ps -a | egrep ' * \.\/command_bin *' | grep -v grep | awk '{print $1}')
/proc/${command_pid}/exe < inpipe 2>&1 &
echo "process ./command_bin running on PID ${command_pid}"
That alone works within the terminal itself. Now if I leave the SSH session open and open another terminal and type ssh root#host "echo command > /root/binary/inpipe" the code gets executed, but then it outputs the command I just typed and its result into the other terminal that stayed open. So it is obviously not an option, I have to capture the output somehow.
If I change ./command_bin & for ./command_bin >outpipe & the program never starts, I have no idea why, I know that because $command_pid is empty and I cannot find the process with ps -A
Now if instead I replace /proc/${command_pid}/exe < inpipe 2>&1 & with /proc/${command_pid}/exe < inpipe &>outpipe & the program starts, I can write to inpipe just fine with echo "command" > inpipe when the script finished running, however if I try any of cat < outpipe, tail outpipe it just hangs, and does nothing. I've tried using nohup when starting the command but it doesn't really help. I've also tried using a normal file for redirecting the output instead of a fifo, but with the exact same results.
I've spent the entire day on this thing and I cannot get it to work. Why is this not working ? Also I am probably just using an awful way to do this, is there any other way ? The only thing that's mandatory here is that I have to connect through ssh to the board and the command line utility has to stay open because it is communicating with onboard devices (using I2C, OneWire protocols etc).
To keep it simple I want to be able to write to the program's stdin whenever I want, get its stdout to go somewhere else (some file, buffer, I do not care) that I can easily retrieve later after an arbitrary amount of time with cat, tail or some other command with ssh.

Unable to run X11 (graphical) programs from atd

I am trying to schedule the execution of a shell-script with the Linux tool "at".
The shell script (video.sh) looks like this:
#!/bin/sh
/usr/bin/vlc /home/x/video.mkv
The "at" command:
at -f /home/x/video.sh -t 201411052225
When the time arrives, nothing happens.
I can execute the shell-script just fine via console or by rightclicking - Execute. VLC starts like it is supposed to. If I change the script to e.g. something simple like
#!/bin/sh
touch something.txt
it works just fine.
Any ideas, why "at" will not properly execute a script that starts a graphical program? How can I make it work?
You're trying to run an X command (a graphical program) at a scheduled time. This will be extremely difficult, and quite fragile, because the script won't have access to the X server.
At the very least, you will need to set DISPLAY to the right value, but even then, I suspect you will have issues with authorisation to use the X screen.
Try setting it to :0.0 and see if that works. But if you're logged out, or the screensaver's on, or any number of other things...
(Also, redirect vlc's stdout and stderr to a file so that you can see what went wrong.)
Your best bet might be to try something like xuserrun.
I suspect that atd is not running. You have to start the atd daemon before (and to set DISPLAY variable like chiastic-security said) ;)
You can test if atd is running with
pidof atd &>/dev/null && echo 'ATD started' || echo >&2 'ATD not started
Your vlc command should be :
DISPLAY=:0 /usr/bin/vlc /home/x/video.mkv
(Default display)

What if we close the terminal before finishing the command?

Let me explain better. What is gonna happen if I run a command in Linux and before it's done and you could enter another command I close the terminal. Would it still do the command or not?
Generally, you must expect that closing your terminal will hangup your command. But fear not! Linux has a solution for that too!
To ensure that your command completes, use the nohup argument first. Simply place it before whatever you are trying to do:
nohup ./some_program
nohup ./do_a_thing -frx -file input_file.txt
nohup grep "something" giant_list_of_files/* > temp_file.txt
The nohup command stands for "no hangup" and it will ensure that the command you execute continues to run, even if you close your terminal.
It depends on the process and your environment (job control shell options, VNC, etc). But typically, no. The process will get a "hangup" signal (message) from the operating system, and upon receiving that, will quit.
The nohup command, for example, arranges for processes to ignore the hangup signal from the OS. There are many ways to achieve the same result.
I would say it will abort att the status you are in just before the session close.
If you want to be sure to complete the job, you will need to use the nohup command.
http://en.wikipedia.org/wiki/Nohup
Read about nohups and daemons (-d)...
A good link is [link]What's the difference between nohup and a daemon?
Worth look at screen command, Screen command offers the ability to detach a long running process (or program, or shell-script) from a session and then attach it back at a later time.

execute a gui application from the command line and send it to the background

Is there a command line utility that I can use for executing X based applications that will detach my applications from the terminal so they aren't closed if the terminal is closed?
I guess such a app could be called something like gnome-run if it existed.
I have tried dtach, but it seems that you have to provide a socket file which is a bit clunky to type. I have also tried nohup, but found that also to be a bit clunky to type by the time std out and err are redirected to /dev/null.
I guess I'm looking for a simple program that will do something similar to this:
#!/bin/bash
nohup $1 > /dev/null 2>&1 &
Yes, there is a way to do it: first you need to run your GUI app and send it to background, then you (probably) want to detach it from Bash task management. For example if I wanted to run gedit this way:
gedit &
disown %1
After that you can close your terminal window and gedit will not be killed. Enjoy!
You already wrote your program, it is called a shell script and you give it the name you like and put it somewhere. Then you either add that directory to your $PATH or in your bashrc you set:
alias gnome-run=<path>/my-awesome-script.sh
Why waste earth's resources on a program?
If you want to run an application (say, gedit) as if it was run from the GUI, use:
xdg-open /usr/share/applications/gedit.desktop
See this answer on superuser.

Linux: using the tee command via ssh

I have written a Fortran program (let's call it program.exe) with does some simulation for me. Via ssh I'm logging ino some far away computers to start runs there whose results I collect after a few days. To be up-to-date how the program proceeds I want to write the shell output into a text file output.txt also (since I can't be logged in the far away computers all the time). The command should be something like
nohup program.exe | tee output.txt > /dev/null &
This enables me to have a look at output.txt to see the current status even though the program hasn't ended its run yet. The above command works fine on my local machine. I tried first with the command '>' but here the problem was that nothing was written into the text file until the whole program had finish (maybe related to the pipe buffer?). So I used the workaround with 'tee'.
The problem is now that when I log into the computer via ssh (ssh -X user#machine), execute the above command and look at output.txt with the VI editor nothing appears until the program has finished. If I omit the 'nohup' and '&' I will not even get any shell output until it has finished. My thought was that it might have to do something with data being buffered by ssh but I'm rather a Linux newbie. For any ideas or workaround I would be very grateful!
I would use screen utility http://www.oreillynet.com/linux/cmd/cmd.csp?path=s/screen instead of nohup. Thus I would be able to set my program to detached state (^A^D) reconnect to the host, retrieve my screen session (screen -r)
and monitor my output as if I never logged out.

Resources