# Help!  Unix (BSD) weirdness on redirect

**URL:** <https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489>\
**Category:** Factual Questions\
**Created:** [January 21, 2015, 4:18pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489 "2015-01-21T16:18:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 4:18pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/1 "2015-01-21T16:18:39Z")

</div>

So, here’s the quick demonstration of the problem:

Make some background processes…

```auto

# sleep 60 & ; sleep 60 & ; sleep 60 & ; sleep 60 &

```

Look at them…

```auto

# jobs
[1] running sleep 60
[2] running sleep 60
[3] - running sleep 60
[4] + running sleep 60

```

Good, right? Let’s count them up:

```auto

# jobs | wc -l
       0

```

Hmm. Where’d the go? Perhaps they’re not giong to STDOUT?

```auto

# jobs 2>&1 3>&1 4>&1 | wc -l
       0

```

…Nope. OK, so I usually think I’m pretty good at this but I’m stumped. Ideas?

This is a BSD-based disk array.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 4:34pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/2 "2015-01-21T16:34:09Z")

</div>

Oh, the shell is BASH. Not much choice on an appliance like this. When I use the alternate Bourne shell, there’s no difference.

---

<div class="post-metadata">

**Author:** ![friedo](https://avatars.discourse-cdn.com/v4/letter/f/8edcca/32.png) [@friedo](https://boards.straightdope.com/u/friedo)\
**Post date:** [January 21, 2015, 4:44pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/3 "2015-01-21T16:44:53Z")

</div>

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.

ETA: does echo $( jobs ); work?

---

<div class="post-metadata">

**Author:** ![septimus](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/septimus/32/410_2.png) [@septimus](https://boards.straightdope.com/u/septimus)\
**Post date:** [January 21, 2015, 5:15pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/4 "2015-01-21T17:15:10Z")

</div>

> [@friedo](#):
>
> … 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.

Rather the opposite, I think.

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.

---

<div class="post-metadata">

**Author:** ![Pasta](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pasta](https://boards.straightdope.com/u/Pasta)\
**Post date:** [January 21, 2015, 5:15pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/5 "2015-01-21T17:15:51Z")

</div>

> [@](#):
>
> ```auto
> 
> # sleep 60 & ; sleep 60 & ; sleep 60 & ; sleep 60 &
> 
> ```

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)”

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 5:20pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/6 "2015-01-21T17:20:39Z")

</div>

Nope. Doesn’t work. I tried back-quotes, no love there, either.

I could really kludge and “ps -e | grep -c \<procname\>” but I’m worried about false positives.

```auto

# jobs
[1] running sleep 60
[2] running sleep 60
[3] - running sleep 60
[4] + running sleep 60
# echo $( jobs );

# echo "`jobs`"

#

```

---

<div class="post-metadata">

**Author:** ![Pasta](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pasta](https://boards.straightdope.com/u/Pasta)\
**Post date:** [January 21, 2015, 5:43pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/7 "2015-01-21T17:43:50Z")

</div>

What if you redirect to a file first:

```auto

jobs > /tmp/foo ; cat /tmp/foo | wc -l

```

---

<div class="post-metadata">

**Author:** ![Pasta](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pasta](https://boards.straightdope.com/u/Pasta)\
**Post date:** [January 21, 2015, 5:46pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/8 "2015-01-21T17:46:09Z")

</div>

By the way, I get the behavior in the OP with tcsh version 6.14.00.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 6:40pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/9 "2015-01-21T18:40:28Z")

</div>

redirect to a file works. Kludgy but no false positives:

```auto

# jobs >out ; wc -l out
       3 out

```

---

<div class="post-metadata">

**Author:** ![Kyrie\_Eleison](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/kyrie_eleison/32/7682_2.png) [@Kyrie\_Eleison](https://boards.straightdope.com/u/Kyrie_Eleison)\
**Post date:** [January 21, 2015, 7:41pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/10 "2015-01-21T19:41:39Z")

</div>

> [@Belrix](#):
>
> redirect to a file works. Kludgy but no false positives:
> 
> ```auto
> 
> # jobs >out ; wc -l out
> 3 out
> 
> ```

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:

```auto

# 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.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 11:01pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/11 "2015-01-21T23:01:52Z")

</div>

Until you posted, I didn’t think I had access to the PPID. I was about to post that this appliance didn’t give me access to PPIDs. Odd little bugger.

Then I remembered, while typing it out, that this is BSD. “ps -al” not “ps -ef”.

I’ll play with the PPID column, should be a pretty easy awk statement.

Thanks for twitching that brain cell.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 11:11pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/12 "2015-01-21T23:11:04Z")

</div>

This is just what I need. Thanks all!

```auto

# cat testit

sleep 120 &
sleep 120 &
sleep 120 &
sleep 120 &
sleep 120 &

MYPID=$$
ps -al | awk '$3=="'$MYPID'" && $0~/sleep/ && $0!~/awk/ {sum++}END{print sum}'

```

…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 ).

---

<div class="post-metadata">

**Author:** ![Derleth](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Derleth](https://boards.straightdope.com/u/Derleth)\
**Post date:** [January 21, 2015, 11:25pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/13 "2015-01-21T23:25:41Z")

</div>

> [@Pasta](#):
>
> What if you redirect to a file first:
> 
> ```auto
> 
> jobs > /tmp/foo ; cat /tmp/foo | wc -l
> 
> ```

Useless Use Of Cat Award goes to…

---

<div class="post-metadata">

**Author:** ![Pasta](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pasta](https://boards.straightdope.com/u/Pasta)\
**Post date:** [January 21, 2015, 11:33pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/14 "2015-01-21T23:33:35Z")

</div>

> [@Derleth](#):
>
> Useless Use Of Cat Award goes to…

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

```auto

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.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 21, 2015, 11:34pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/15 "2015-01-21T23:34:21Z")

</div>

well, I can see doing it to avoid having to snip off the numeric with awk or something.

either:  
jobs \> /tmp/foo ; cat /tmp/foo | wc -l

…or…  
jobs \> /tmp/foo ; wc -l /tmp/foo | awk ‘{print $1}’

there’s probably some smart kernel reason to do one over the other.

EDIT: or what \*\*Pasta \*\*said.

---

<div class="post-metadata">

**Author:** ![Kyrie\_Eleison](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/kyrie_eleison/32/7682_2.png) [@Kyrie\_Eleison](https://boards.straightdope.com/u/Kyrie_Eleison)\
**Post date:** [January 21, 2015, 11:40pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/16 "2015-01-21T23:40:28Z")

</div>

> [@Belrix](#):
>
> …its funny to see different shell programming styles. I always insist on single quotes around awk statements, changes how we escape to external variables.

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.

---

<div class="post-metadata">

**Author:** ![Kyrie\_Eleison](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/kyrie_eleison/32/7682_2.png) [@Kyrie\_Eleison](https://boards.straightdope.com/u/Kyrie_Eleison)\
**Post date:** [January 21, 2015, 11:53pm UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/17 "2015-01-21T23:53:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 22, 2015, 12:04am UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/18 "2015-01-22T00:04:22Z")

</div>

The double quotes in “’$MYPID’” (double, single, external variable, single, double) are probably unecessary. It forces the string comparison rather than a numeric comparison.

Just habit.

---

<div class="post-metadata">

**Author:** ![Belrix](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@Belrix](https://boards.straightdope.com/u/Belrix)\
**Post date:** [January 22, 2015, 12:10am UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/19 "2015-01-22T00:10:03Z")

</div>

…and I didn’t even think of the redirect into “wc” for the other option. Tighter still, I bet.

---

<div class="post-metadata">

**Author:** ![Pasta](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pasta](https://boards.straightdope.com/u/Pasta)\
**Post date:** [January 22, 2015, 3:25am UTC](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489/20 "2015-01-22T03:25:12Z")

</div>

> [@Kyrie\_Eleison](#):
>
> 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.

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 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.

I’ve always used this construction:

```auto

export FOO="Hello"
echo world | awk '{print ENVIRON["FOO"],$1}'

```

[Next page](https://boards.straightdope.com/t/help-unix-bsd-weirdness-on-redirect/710489.md?page=2)
