Preventing background process from writing to console - linux

In Linux's bash, I know how to start a long running process and send it to the background.
For example run.sh, then press Control+Z, then type bg 1
Sometime I would like to continue do other work, but this background process keep printing to my Putty console - which is annoying.
I know I can start the run.sh &> /tmp/run.sh.log thus pumping all output to /tmp/run.sh.log but sometime I just forgot to do so.
How do I stop that background process from printing to my console?

If you have started the process already and want to stop it from printing to stdout, while still keeping it running, you may use:
stty tostop
When you give stty the tostop argument it stops the background processes that try to write to stdout
To enable the process to write again you may use fg.
Original source can be found here

Control+Z is stopping your job (like pausing it) that's why you don't see the output. fg 1 makes it to reasume
To suppress all messages redirect everything to /dev/null
./your_script.sh 2>&1 &

Related

How do I terminate a command that runs infinitely in shell script?

I have this command in my shell script that runs forever- it wouldn't finish unless I do ctrl-c. I have been trying to look up how to send ctrl-c signal to script and all the answers have been some sort of kill $! or kill$$ or such. My problem is that the command never finishes, so it never goes on to the next command like my "kill" commands or anything else. I have to manually hit the ctrl-C in my terminal for it to even execute kill $!. I'm sure there is a way to work around this but I am not sure what. Thanks in advance!
There are several approaches to this problem. The simplest (but not most robust) is (perhaps) to simply run your long running command in the background:
#!/bin/sh
long-running-command & # run in the background
sleep 5 # sleep for a bit
kill %1 # send SIGTERM to the command if it's still running

Detaching a background process in zsh so that I can close the terminal

I have a terminal process running zsh in the Cygwin environment. I want to start a background process and then close the terminal process and have the background process running. However, when I exit the terminal, I get the error message that it can't exit, because a background process is still running. Example:
sleep 300 &
exit
I get the message zsh: you have running jobs.
The same with
nohup sleep 300 &
From the man page of zsh, I see that there is a command called disown which, from the description, might do what I want, but I don't know how to use it. According to the man page, it expects an argument job, but doesn't say what this argument actually is. I tried
sleep 300 &
disown $!
but get the message disown: job not found: 3964, so a job is obviously not a PID.
How can I do this correctly?
You need to refer to the job by it's job number
sleep 3000
control-z
bg
jobs
disown %3 (or whatever job number)
Hope this still helps at lest other readers: disown without any parameter disconnects the job with job number %1.
In addition you might want to check out the AUTO_CONTINUE on Ctrl-Z function.
alias bg='bg && disown'
in .zshrc to get bash-style behavior exiting terminal that launched process with keystrokes: Ctrl + Z, bg, exit

how can I continously run a unix script in background without using crontab.

how can I continously run a script in background without using crontab. The script should run even after I logout and is acceptable if it doesen't start after system reboot.I am new to unix.
There's a couple of ways of doing this but the neatest way is to use screen. This lets you create a session which lives perminently on the machine and you can simply reconnect to to check on the progress of your long running process.
If you don't wish to use screen you can use nohup this allows you to run a task like:
nohup mytask &
Your task will now run in the background and will survive a log off, however there's no way to take control of it again, unlike with screen.
if [ "x$1" != "x--" ]; then
$0 -- 1> /dev/null 2> /dev/null &
exit 0
fi
This is how you can run a script as a daemon. First your script (the father) will create a copy of himself (a child) so it is considerd as a process of the father. Then the father kills itself while the child is still running. Guess what happens when you do such a thing ? The child is attached to the init process. So even if you logout, the script will still run.
You can even start it without the "&" operator because you start the father which is killed a millisecond after.
You can take control over it again like any program running on your computer.
By the way it's not a real "daemon" program, it's just kind of emulation. You can't just start it at the boot (I mean really the BOOT and not the loggin) if you want to start it as you login, quite simple put it in your .xinitrc
The main advantage of this solution is that your script doesn't depend on any other programm such as "nohup" which is really bad I think.
Regards
PS : If you want some informations about what the command above does, just ask me. It's just a "parameter" thing.
As others have mentioned before, you need to use nohup to prevent the process from getting the hangup signal (hence no-h-up).
However, if you start the process in the background to begin with, as
prompt> nohup process &
that has the disadvantage of not allowing you to enter any data that may be required to get the process started off. This may be passwords/credentials or other input the process needs.
If you have that requirement, start it without the "&" at the end, enter your input and then hit Ctrl-Z to put the process to sleep. To send it to the background, type "bg" at the prompt and hit Enter.
prompt> nohup process
Enter password:
(Now press Ctrl-Z)
[1]+ Stopped process
prompt> bg
[1]+ process &
Now even if you log off, the process will continue to run in the background.
Alternatively if you are using bash or zsh, if you didn't start the process with nohup to begin with, and killing it and restarting is not an option then you can use the built-in disown command. First pause and background the process. And then stop hangup signals from reaching it.
prompt> process
Enter password:
(Now press Ctrl-Z)
[1]+ Stopped process
prompt> bg
[1]+ process &
prompt> disown -h
Note: If you've got other background jobs running, you need to provide the jobspec to only disown this specific job.
prompt> disown -h %1
Instead of [1] if you'd seen [2] when you paused and sent the process to the background, you'd say disown -h %2 instead.
As well as starting it in the background, as above, you may need to use 'nohup'. This means it will carry on running, even if you close the terminal.
nohup ./abc.sh &
start it in background using & operator e.g.
./abc.sh & this will continue till (a) the execution is complete or (b) you kill it or (c) system reboots

Running a process that waits on input in the background, without it pausing and without sending input

I have a program that does something like this in order to wait on someone pressing enter in order to quit:
spawnThreadAndDoStuff();
System.in.read();
System.exit(0);
I want to run it in the background indefinitely from a script, and just go kill it when I want it to end. I thought reading input from /dev/null would do this, but it doesn't seem to be working. My script looks like:
#!/bin/bash
java -cp someapp > mylog.log < /dev/null &
Am I doing this wrong, or is my approach just way off? What would the correct way to handle this be?
Reading from /dev/null does not work because read immediately returns with an end-of-file.
This works for me:
(while true; do sleep 10000; done) | java -cp someapp > mylog.log &
The first command just sleeps forever, never providing any input.
What you're doing wrong is that input from /dev/null behaves like a 0 byte file, and so the process hits EOF on standard input and quits. If /dev/null could hold a process that expects input, then this would work:
$ cat < /dev/null
But of course cat exits right away.
You're being bitten by the problem that you have a program with threads which reads from the TTY. As soon as you background it, because it is reading from the TTY, the tty driver sends it a SIGTTIN which stops all of its threads.
I would just rethink that program. If you want a program to work well in the background, do not have it read user input as a termination signal. Get rid of that read and kill it with signals when you want it to stop.
If you want both behaviors (background mode and user-quit mode) then make the program run-time configurable. One way would be simply to detect whether standard input is a TTY device or not. If it is a TTY device, then do the TTY read and quit. If it is not a TTY, then don't read: do an infinite sleep instead. Then your /dev/null standard input trick should work. /dev/null is not a TTY and so the process will just sleep.
(Do you have the isatty function in Java?)
command ... &
thePIDofCOMMAND=$!
.... do stuff
kill $thePIDofCOMMAND

Asynchronous shell commands

I'm trying to use a shell script to start a command. I don't care if/when/how/why it finishes. I want the process to start and run, but I want to be able to get back to my shell immediately...
You can just run the script in the background:
$ myscript &
Note that this is different from putting the & inside your script, which probably won't do what you want.
Everyone just forgot disown. So here is a summary:
& puts the job in the background.
Makes it block on attempting to read input, and
Makes the shell not wait for its completion.
disown removes the process from the shell's job control, but it still leaves it connected to the terminal.
One of the results is that the shell won't send it a SIGHUP(If the shell receives a SIGHUP, it also sends a SIGHUP to the process, which normally causes the process to terminate).
And obviously, it can only be applied to background jobs(because you cannot enter it when a foreground job is running).
nohup disconnects the process from the terminal, redirects its output to nohup.out and shields it from SIGHUP.
The process won't receive any sent SIGHUP.
Its completely independent from job control and could in principle be used also for foreground jobs(although that's not very useful).
Usually used with &(as a background job).
nohup cmd
doesn't hangup when you close the terminal. output by default goes to nohup.out
You can combine this with backgrounding,
nohup cmd &
and get rid of the output,
nohup cmd > /dev/null 2>&1 &
you can also disown a command. type cmd, Ctrl-Z, bg, disown
Alternatively, after you got the program running, you can hit Ctrl-Z which stops your program and then type
bg
which puts your last stopped program in the background. (Useful if your started something without '&' and still want it in the backgroung without restarting it)
screen -m -d $command$ starts the command in a detached session. You can use screen -r to attach to the started session. It is a wonderful tool, extremely useful also for remote sessions. Read more at man screen.

Resources