Solved Sending string to standard input of program in background(suspended).

Hello,
I want to have program running in background on my server (even after closing shell) and I need sometimes to send some string command to it from scirpts.

First I wanted to try in console:

Code:
user@jomo:~ # MyProgram

Hello text of MyProgram
^Z
Suspended

user@jomo:~ # jobs -l

[1]  + 12345 Suspended                     MyProgram

user@jomo:~ # echo "text_to_input" >> /proc/12345/fd/0
/proc/12345/fd/0: No such file or directory.

I think I need to run it as daemon to make it run after closing shell, but first is how to write to standard input/read from standard output? My /proc is empty. I can't find it in doc.
Is it becouse it is suspended?

What am I missing?
 
I think FreeBSD in it's default settings does not mount a procfs. But you can do that yourself, see procfs().

The & operator makes a command run in the background.

One way of sending Information to a program would be a pipe, like in echo "password" | sudo -S whoami.
 
The program has to await for input even after closing terminal, bg command doesn't allow that. I can't rerun program every time I use command.

I will learn more about nohup, mkfifo and fdescfs. I tried to use nohup but it closes program when I close terminal.

Maybe I should make this program service and make rc.d script in /usr/local/etc/rc.d/MyProgram ?
 
In csh & tcsh, nohup(1) is a builtin(1). You have to explicitely use the standalone executable, i.e. either give the path or precede w/ a backslash. Install the docs and cruise through them, and have a look in /usr/share/examples.
 
I want to have program running in background on my server (even after closing shell) and I need sometimes to send some string command to it from scirpts.

First I wanted to try in console:

Code:
user@jomo:~ # MyProgram

Hello text of MyProgram
^Z
Suspended
Excellent. You have tried running your program from the console, and demonstrated that it works. Maybe you could even have tested giving it some input strings right there.

But now, after typing ^Z, the program is suspended, and is NOT running. As other posters already said, if you want the program to continue running, you either have to say "bg" at this point (which tells the program to start running again, and sends it to the background), or you need to start it with an "&" at the end of the command line in the first place.

Code:
user@jomo:~ # echo "text_to_input" >> /proc/12345/fd/0
/proc/12345/fd/0: No such file or directory.
Two problems here. To begin with, this is FreeBSD, not Linux. FreeBSD by default does not have a proc file system. Yes, there are some makeshift equivalents you can install, but that sounds like a bad idea. When in Rome, do like the Romans. When on FreeBSD, use the appropriate tools. I wouldn't bother with fdescfs, since it doesn't get you much further.

Second: While you are on Linux, look carefully at the content of /proc/12345/fd/0. That is not a pipe that you can add data to. It is simply a soft-link to a terminal or pseudo-terminal device. That's because when you started the program, it (implicitly) opened its standard input (the file descriptor from which it reads your string commands), and attached it to a terminal. And it will stay attached to that terminal, and there is nothing you from the outside can do about that (*). What you need to do if you want to speak to the program while it is running is to attach its standard input to something that can receive data (other than from a keyboard), and that is exactly the function of a fifo. Something like this should work: "mkfifo my_input_fifo; my_program < my_input_fifo & ; echo "hallo please do something" > my_input_fifo".

(*) Footnote: The program is free to close its own input that comes from the terminal, and reopen a new input. Most programs will not do that, but there is nothing that prevents you from adding that to the code.

I think I need to run it as daemon to make it run after closing shell, ...
There is a variety of things you can (and have to) do. The easiest way to run it "in the background" (which gets you halfway there) is to add a "&" after the command line. But like that, the program is still in the process group of the shell you are running, and will get killed with the shell exits. The reason this is called "hup" is that it is implemented by delivering the "hangup" signal to various processes, and that signal is called "hup". The way around that is to use "nohup my_program &" (probably with the "< my_input_fifo" added in the middle).

By the way, you still probably want to deal with the standard output and error of the program going somewhere sensible.

Maybe I should make this program service and make rc.d script in /usr/local/etc/rc.d/MyProgram ?
You can, but most likely that is total overkill. A service is typically something that runs every time the computer is booted, and serves the whole computer. If that pattern fits your program, by all means go ahead. But more likely, this is a thing that is only used sometimes, and only by one user, in which case creating a fifo and using "nohup ... < ... > ... &" is more appropriate and reasonable.

If you want to turn your program into a service, you need to first solve all the same problems: create a fifo for input, and deal with output. But then you also need to find a way to cleanly shut down your program. Furthermore, services usually run as root. Is your program secure enough to run as root? Have you audited the source code? And typically, services that want to be reliable have to do a lot of things, like make sure only one copy is running, changing their current directory to root (so they survive file systems being mounted and dismounted), detach from controlling terminals (to solve the hup problem), fork a few times (for reasons I forget), close extra file descriptors, drop privileges, handle signals, and perform logging via syslog. That's a huge amount of extra work (easily 100 extra lines of python, or 300 of C), and I just don't see the benefit.

If you access to the source code of the program, I would integrate creating the fifo (for standard input) and redirecting standard input right into the source code. Makes it more convenient.
 
...Install the docs and cruise through them...
I red how it work and nohup didn't work becouse of me. My main loop had following code :
C++:
do {
    if (argc == 1 && !getline(cin, cmd)) {
          cmd = "exit";
        }
        //... other commands in else if...//
    } while (cmd != "exit" && argc == 1);

So it was closing anyway (EOF makes true). I have written it for windows shell so now I had to change it. Now this works properly:
Code:
nohup /usr/local/bin/MyProgram > /usr/outstk.log &

I've never tried this, but I'm guessing what you want is a FIFO. See mkfifo(1).
What you need to do if you want to speak to the program while it is running is to attach its standard input to something that can receive data (other than from a keyboard), and that is exactly the function of a fifo. Something like this should work: "mkfifo my_input_fifo; my_program < my_input_fifo & ; echo "hallo please do something" > my_input_fifo".

You are right, that what I was looking for. I suppouse that I can handle output with this too. For now I saved output to .txt.

Furthermore, services usually run as root. Is your program secure enough to run as root? Have you audited the source code? And typically, services that want to be reliable have to do a lot of things,
Code is mostly mine, memory seems to be ok but maybe I'll be running it on every thread and it can eat all resources (it is a feature). So service is not good idea for that I suppouse.

If you access to the source code of the program, I would integrate creating the fifo (for standard input) and redirecting standard input right into the source code. Makes it more convenient.
That is how I'm going to do this. I'll try for output too, as it is defined what I need from input and output.

Thanks all for input and additional information about solutions.
Cheers.
 
Back
Top