Running some netperf tests in a while loop like so under /bin/sh, I'm running into cases where the while loop continues to loop, even after I mash on ^C (which I would expect to kill netperf eventually -- works on 9.1-RC1, but not 7.4-STABLE) or ^Z (I would expect job control to stop spawning jobs, but it doesn't in either version): bf049# exec sh wf048# exec sh $ while : ; do netperf -cCjt TCP_STREAM -H 10.7.187.52 -l 10 -- -D; done .. ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^ZTCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo Recv Send Send Utilization Service Demand Socket Socket Message Elapsed Send Recv Send Recv Size Size Size Time Throughput local remote local remote bytes bytes bytes secs. 10^6bits/s % C % C us/KB us/KB 65536 32768 32768 10.01 810.28 8.05 7.52 3.254 6.080 TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.56 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo Bash on the other hand does stop the code snippet: $ while : ; do netperf -cCjt TCP_STREAM -H 10.7.187.52 -l 10 -- -D; done TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.7.187.52 () port 0 AF_INET : nodelay : histogram : interval : dirty data : demo ^Z [1]+ Stopped netperf -cCjt TCP_STREAM -H 10.7.187.52 -l 10 -- -D The expected behavior isn't documented in sh(1) and in the opengroup sh(1) manpage. How-To-Repeat: exec sh while : ; do netperf -cCjt TCP_STREAM -H $IP -l 10 -- -D; done You could probably replace the second command (to netperf) with something that blocks.
> [while : ; do netperf -cCjt TCP_STREAM -H 10.7.187.52 -l 10 -- -D; done > works strangely with ^C/^Z] For the case with ^C, I indeed deliberately fixed that for 9.0. For the case with ^Z, this is indeed a caveat that is complained about more frequently, and different shells handle it differently because POSIX leaves it vague. POSIX discusses suspending jobs (process groups), but a sequence or while loop is not a job. One workaround is to make it a job by placing parentheses around the loop. With most shells, this creates a new process group and job that can be suspended normally. An exception is ksh93 which attempts to execute the subshell in the same process; I do not like this but I think POSIX permits it (and in non-interactive or no-job-control mode it is fine to execute a subshell in that way). What sh does is return status 146 (128+SIGTSTP) and continue (so while netperf; do :; done will abort if ^Z'ed). What bash appears to do is break loops if something was ^Z'ed. What zsh appears to do is fork and continue the loop after the suspended process terminates. However, it gets $? wrong. Also, it needs a fair bit of code and changes to the shell environment after the suspension do not affect the parent. -- Jilles Tjoelker
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped