This version always reports that the first command has had no output, since the PID line is shadowing it. If I add even a file redirect after the program name, the kill command stops working since it is now pointing at the redirect.

Edit: I am on Ubuntu 16.04; the output of bash --version is GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

2 Answers
2

Indeed, in your code diff receives the output of kill instead of program. You can solve this by compounding the commands before the pipe in a subshell with ().

Another potential issue with your script is that kill is not designed to wait for termination of program; instead it just sends a signal to it. Therefore you may see a race condition where diff works without catching the whole output of program. I advice to programatically wait for termination of the backgound process with the wait bash builtin.

There is no termination of the background program, that's why I want to send a SIGSEV. The program expects to be ended early by the user pressing CTRL-C, so waiting will wait forever.
– Alex VermillionMar 17 '19 at 4:44

I see. In this case the wait is not required.
– coolparadoxMar 17 '19 at 4:57

@AlexVermillion The wait will not wait forever if there's no background tasks to wait for. In the submitted code, the wait would wait for the task to terminate (it may do some cleanup or processing when it receives the INT signal, which may take a bit of time).
– Kusalananda♦Mar 17 '19 at 8:41

@Kusalananda In this case, it does wait forever. For some reason, although the parenthesis block is being exited, the program is not actually being killed. I can tell by checking top after and seeing it is still running. I am confused, because running the kill -INT $PID on the command line after properly setting the variable does kill it. I can tell that the kill command is passed by putting a touch blah.txt afterwards.
– Alex VermillionMar 18 '19 at 2:51

If your_program is able to generate huge amounts of data in a second (as when testing with yes(1)), then diff will have a lot of trouble coping with, and unless you have some careful limits put in place, it may blow your memory and hang up your machine (and in the best case it will create the illusion that the command is "hanging" for a while). Instead of yes, try it with a slowyes script like while echo y; do sleep .01; done.

Notice that a <(...) process substitution runs in parallel, so diff will not wait for it to finish before starting to process its data.

I guess you will be better served by stopping your_program after it has generated a number of lines, instead of after a period of time:

diff -y output1.txt <(your_program | head -n 1000)

In this case, your_program should be killed by SIGPIPE, as usual with the left side of a pipeline. If your program is ignoring both SIGPIPE and write(2) errors, then please make another question about that, either how to fix it or how to work it around.

[1] if your shell does not support process substitutions (as the /bin/sh on debian, which is not bash), you can also use a pipeline, as in the other answer

The output of running the program is silenced in the first command since it is hidden behind a semicolon. I did not test the second as the program has 3 lines of output only. The third snippet fails for the same reason as the first.
– Alex VermillionMar 17 '19 at 22:05

Can you perhaps provide an exact snippet you have tested this with? When I test with yes, there is not any output, which is the only part I am having a problem with as the rest works.
– Alex VermillionMar 17 '19 at 22:06

"The output of running the program is silenced in the first command since it is hidden behind a semicolon". No. That's not how it works. The semicolon doesn't hide anything. You can try with any program you want -- it will work exactly as I described, including why there's "no output" with yes(1).
– mosvyMar 17 '19 at 22:10

1

@AlexVermillion There are a lot of reasons why your_program could fail to produce any output; for instance, it may use buffering when not outputting to a terminal, and not flush its buffers when killed by a signal. But there are thousands of possible scenarios like that.
– mosvyMar 17 '19 at 22:54

I have been running these commands and taking my best guess at what silences them. It's a very short C program that terminates when fed a certain letter or else does a simple array operation. It will not terminate if left alone, but the output that I know is happening does not show in the diff, only when followed by other commands, as if its stdout is ignored by the pipe.
– Alex VermillionMar 18 '19 at 17:47