It seems to work fine on darwin bash. I’ll note that ‘jobs’ is a shell builtin so depending on how your shell is set up (if it’s a weird embedded thing, for instance) it may not be launching it as a subprocess with its own stdout.
To implement the pipe (" | wc"), the shell launches a subshell to run ‘jobs’. And that subshell jobs prints nothing because it has no jobs: the jobs belong to its parent.
As an aside, those semicolons are redundant. The “&” serves to delimit the commands. What you wrote says “run sleep in the background, then a null command interactively, then sleep in the background, then…”
ETA: And, yeah, I get the expected output (non-zero line count) in “GNU bash, version 3.2.25(1)-release (i686-redhat-linux-gnu)”
If you want to avoid the temp file, you could use ps, selecting lines with matching parent PIDs to weed out false positives. Here’s a working command line under Linux. ps arguments and line format will likely vary on your BSD box, but it illustrates the idea:
# We have some potential false positives running. Header line, although
# actually eliminated by grep, was manually inserted for clarity's sake.
# Dump full process table, grep for sleep
[kyrie@ghost ~]$ ps -eF | grep sleep
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
kyrie 10817 1120 0 26971 516 4 14:08 pts/0 00:00:00 sleep 1000
kyrie 10855 1120 0 26971 516 4 14:17 pts/0 00:00:00 sleep 1000
kyrie 10882 10776 0 28159 944 5 14:20 pts/1 00:00:00 grep --color=auto sleep
# Start the jobs we actually want to detect.
[kyrie@ghost ~]$ sleep 60 & sleep 60 & sleep 60 &
[1] 10884
[2] 10885
[3] 10886
# Here are the jobs we actually want to detect. We should see three.
[kyrie@ghost ~]$ ps -eF | grep -v awk | awk "\$3 == $$ && /sleep/ {print}" | wc -l
3
Not knowing your exact situation, a caveat: Being under job control, and having a given shell as your parent are not exactly the same thing. But you did previously mention that using ps might be an option if you could eliminate false positives, so I suspect that this, or something very similar might work for you.
…its funny to see different shell programming styles. I always insist on single quotes around awk statements, changes how we escape to external variables. I always back-quote to run a external command while friedo does a $( cmd ).
Um… Not useless. Intentional. His original design would have the output be a single number. To preserve that behavior, one needs to recover a stream to pipe to ‘wc’. Doing "wc -l /tmp/foo’ produces a second field, namely the filename, which was not prescribed. You could do something like
wc -l /tmp/foo | cut -d ' ' -f 1
to restore the original behavior, but as long as you’re using a second process, ‘cat’ is a much better choice.
Now, I’m curious. I usually use single quotes around awk statements, too, but I switched to the more cumbersome double-quotes because it’s the only way I know that still allows the shell to expand shell variables inside the statement. How do you do that inside of single quotes?
Edit to add: I think what Derleth was getting at is that “wc -l < /tmp/foo” would do as well as “cat /tmp/foo | wc -l”. No need for awk to snip.
And I missed the edit window for a second edit: Never mind answering my question. Having looked more closely (i.e. at all) at the code text in your post, I understand the style you employ.
The double quotes in “’$MYPID’” (double, single, external variable, single, double) are probably unecessary. It forces the string comparison rather than a numeric comparison.
I suppose. The commonality of “UUOC” admonitions is a pet peeve of mine, as I feel they are often misguided and are a damagingly extensive form of premature optimization. But that’s a rant for another thread…
I’ve always used this construction:
export FOO="Hello"
echo world | awk '{print ENVIRON["FOO"],$1}'