7

I can grep the output of jobs, and I can grep the output of a function. But why can't I grep the output of jobs when it's in a function?

$ # yes, i can grep jobs
$ jobs
[1]+  Running          vim
[2]+  Stopped          matlab

$ jobs | grep vim
[1]+  Running          vim

$ # yes, of course i can grep a function
$ type mockjobs
mockjobs is a function
mockjobs ()
{
    echo '[1]+ Running         vim banjo'
}
$ mockjobs | grep vim
[1]+ Running         vim banjo

$ # now put those two together and surely I can grep???
$ type realjobs
realjobs is a function
realjobs ()
{
    jobs
}
$ realjobs | grep vim
$ # Nope, WTF?

$ bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

$ # funny though, redirection works just fine:
$ tmpfile=$(mktemp); realjobs > $tmpfile; grep vim $tmpfile; rm $tmpfile
[1]+  Running          vim

I'm not seeing a bug in the bash list, but maybe I missed it? There's reference to an issue in Bash 2.02 when jobs is part of a pipeline, but nothing recent and in a function that I can find.

What am I missing here?

  • 1
    +1; the source seems to indicate that jobs would print to stdout – Jeff Schaller Apr 27 '16 at 20:33
  • Uh... I'd open a bug against bash, as this is wacky. – thrig Apr 27 '16 at 21:16
  • 1
    echo "$(realjobs)" | grep vi works too. – cas Apr 28 '16 at 7:18
  • It don't work in function too.function testjobs(){jobs | grep vi}andfunction testrealjobsgrep(){realjobs | grep vi}.The testjobs can work,but the testrealjobsgrep can't work. – user164825 Apr 28 '16 at 8:21
8

Eric Blake answered on the bash-bugs mailing list:

jobs is an interesting builtin - the set of jobs in a parent shell is DIFFERENT than the set of jobs in a subshell. Bash normally creates a subshell in order to do a pipeline, and since there are no jobs in that subshell, the hidden execution of jobs has nothing to report.

Bash has code to special-case jobs | when it can obviously tell that you are running the jobs builtin as the sole command of the left side of a pipe, to instead report about the jobs of the parent shell, but that special-case code cannot kick in if you hide the execution of jobs, whether by hiding it inside a function as you did, or by other means such as: eval jobs | grep vim

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.