What is wrong with running unix processes with &? - shell

I have seen tools to daemonize processes.
But I have seen that:
some_command &
Runs process in a daemonized way, is this way bad? how is this way called?
Update
My doubt is that I am calling that command inside an ssh session, will the process last after closing ssh session?

That's not daemonized, that's simply running it as a background process.
A true dameon is a lot more involved; see e.g. http://en.wikipedia.org/wiki/Daemon_(computer_software)#Creation.

The & is an important little character in UNIX; it means "run the command in the background"; i.e., detach it from the window it was started from, so it does not block the command line.
Should the program ever try to read from the terminal window, it will be suspended, until the user "brings it to the foreground"; i.e., brings it to the state it would have had without the & to begin with.
To bring a program to the foreground, use "fg" or "%". If you have more than one background job to choose from ("jobs" will show you), then use for example "%2" to choose the second one.
Important:
If you forget to give the & at the end of line, and the process blocks the command input to the terminal window, you can put the process in the background "after the fact", by using Ctrl-Z. The process is suspended, and you get the command prompt back. The first thing you should do then is probably to give the command "bg", that resumes the process, but now in the background.
http://www.astro.ku.dk/comp-phys/tutorials/background.shtml

Related

Is prompt available in Vte?

I have a shell running in a Vte.Terminal widget (could be bash, zsh, or any other interactive shell), I would like to monitor it so as to know when the prompt is available and a new command can be started.
I can't seem to come up with a consistent method.
Here are the ideas I've thought of so far:
Monitor for child process exit.
Could work some of the time, but commands that use only built-ins wouldn't spawn a child. (example: "while true; do; echo test; done;") Also When a command is started in background the prompt would be available before the child exited.
Watch for prompt string in Vte output.
Two problems: 1. A simple prompt string such as "#>" could easily be outputted by some script and give a false positive. 2. Knowing what the prompt string is, is problematic.
Any other ideas or a way to get one of the above working?
What my purpose is.
I'm working on a terminal emulator and would like to change the icon based on whether the prompt is available. Also I am attempting to allow commands to be 'queued' to run when next possible.

creating a new screen (like vi and less does) in a textual program

Programs like vi, less, screen, when executed, they fill the terminal with their data, and then, if you press c - Z (or terminate the program) the terminal return as it was before the execution of these programs.
How usually a program do that? What is the correct terminology this kind of thing?
PS: The words used in the title may be not correct since I've no even idea about the terminology of this kind of things.
EDIT:
Thank to #Atropo I now know the correct name of these is foreground process,
but, how a program do that? How the program can clear the screen, do its writing and, at the end of the execution, let the shell reappear with all the old writings?
They're called foreground processes.
Usually a foreground processes show the user an interface, through which the user can interact with the program. So the user must wait for one foreground process to complete before running another one.
While you use a foreground process the shell prompt disappears until you close the process or you put it in the background.
By default CTRL-C generates SIGINT signal and CTRL-Z SIGTSTP:
https://en.wikipedia.org/wiki/Unix_signal
To change the behavior you can:
redefine or mask signal handler
disable the key combination for stdin http://linux.die.net/man/3/termios
close stdin descriptor (like daemons do)

Can I trap control-q and control-s in ruby?

For some signals, like SIGINT, I can easily enough set up a trap to handle the signal and continue execution as I see fit. I'd like to add typical behavior for ^q and ^s to a ruby command-line application that I'm fiddling with. Is there a way to do this - particularly, one that is portable so I can use it in Windows, iOS, Linux and Solaris?
EDIT:
It turns out that the signals are never delivered to the process. In fact, running strace on the process and on its parent process, a bash instance, showed that neither the process nor the parent were getting any indication of what was going on. They're simply being suspended.
I may try to have a SIGALARM handler that fires once per second, checks to see if much more than a second has passed since the last alarm, and makes appropriate calls if it concludes that the process has been suspended. There would be false positives on a heavily-loaded system.
In irb enter Signal.list. It will list all the signals you should be able to trap.
Trap a signal in ruby:
Signal.trap("STOP") do
# handle the signal
end
In the terminal enter $ stty -a. It should list signals and their associated key combo (if they have one).
I believe ^s is usually stop and ^q is start.
Although according to this answer, those key combos do not actually send a signal to the running process, but instead to the terminal driver. In that case, kill -STOP <process> can send that signal to your process.
TL;DR No, you can't trap them, because they don't result in signals and the processes under the terminal don't see them and can only detect them heuristically. However, if the point is to be able to use those keybindings in your terminal program, then yes, you can do that by disabling the terminal's special treatment of them.
^q and ^s don't result in signals. It's ^z not ^s that results in the terminal signaling SIGSTOP (EDIT: It's actually SIGTSTP).
What ^s does is tell the terminal to not read the output of the processes that are writing to it. This causes the processes to block on write to the terminal (they can still write to other places and read from stdin, as well as do other things)[1]. ^q tells the terminal to continue reading and displaying the processes output. The processes that have the terminal as standard input don't see these. The terminal sees the keybindings, acts on them, and doesn't pass them on to the processes reading from its terminal device.
You can disable this special behaviour with stty -ixon, and re-enable it with stty ixon. When I disable it, the process that reads while I type says that ^s is byte 0x13, and ^q is byte 0x11.
[1] As an experiment to show this, you can open 2 terminal windows. Execute tty on the second one to find its terminal device. Then, on the first terminal, you can run tee $TTY > $OTHER_TTY with $OTHER_TTY being the terminal device of the second terminal. Once you've done that, you can hit ^s to block writes to the terminal and check this by typing some line. That line will be displayed in the second terminal, but not the first, and thereafter nothing you type will be displayed on either until you hit ^q. What happened here is that after you hit ^s and typed a line, tee could still read it, and output it to its stdout which we redirected to the second terminal. Then, when it tried to write it to the first file passed as argument it blocked because it was the terminal you blocked with ^s. It stayed there waiting for write() to return which it won't until you hit ^q.

Why might ruby fail to recognize that a child process (opened using popen) has terminated?

The child process is launched using the following code:
IO.popen("/path/to/process/in/question") do |command|
command.each do |line|
puts line
end
end
puts "Child Process Complete"
The individual lines output by the child process are correctly shown on the console up to and including one immediately before the process exits. However, the message "Child Process Complete" is not shown until I hit ctrl-c.
A similar process, triggered using the same mechanism, is correctly recognized as having terminated, so the problem is probably a result of something that the child process is doing. Unfortunately I have no idea what that something may be.
[Edit] I should probably also mention that the child process can also be triggered directly from the command prompt, and that no issues are observed when doing so.
Benoit Garret put me onto the right track when he suggested that something was waiting for user input. In attempting to sanitize the child process script (and the things it called in turn) I stumbled upon what appeared to be an error in a script lower down (which has been sitting there unnoticed for several years).
The Ruby code, posted above made a call to an initial shell script. That in turn was calling a second shell script which contained the following abomination:
(some_application) &
>/dev/null 2>&1
I'm not sure if this is what happened, but the way I read this is that some_application gets started and run as a background process. Standard output gets redirected to /dev/null and standard error gets redirected to standard output... but which process does this redirection relate to?
Changing the call to
some_application >/dev/null 2>&1 &
(I.e. run some_application throwing away standard out and capturing standard error to the console) made all my problems go away.

powershell bash loops are randomly stuck waiting for keyboard input

I have bash script I am running from powershell in windows that does a for loop. Every once in a while, one of the loop iteration hangs until I hit enter on the keyboard.
This doesn't happen all the time, in fact, it happens pretty rarely, but it still does.
The interesting thing is that my loop innards is basically time _command_ and so after I hit enter, it'll tell me how long the command took to run. The command actually takes way less time to execute than the loop iteration takes - because it's waiting for keyboard input for some odd reason.
It's pretty annoying to leave a script running overnight and come back in the morning to see that it didn't get very far.
Does someone knows WHY this happens and WHAT to do to get around it?
Thanks,
jbu
I have encountered the same problem several times. Now I guess I have found the reason!
If you ever press the mouse within the powershell, it might get stuck and need user to press "enter" to continue. So the get-around-way is to make sure that you didn't accidentally press your mouse within the shell window while you are already running some program...
Goto the powershell properties and unselect 'Quick Edit'/'Insert' check boxes. If these are selected, the console pauses output and resumes only when an Enter key is pressed ( You can identify this by monitoring the console title bar- it will switch from "Administrator:Windows PowerShell" to "Select Administrator:Windows Powershell"
Until you post the script, there's little we can do to help.
However, in general, one of your commands probably returns a null once in a while as input to stdin of another command which, upon seeing null looks to the terminal as stdin. Or something along those lines.

Resources