Jimmy Johnson
Jimmy Johnson

Reputation: 908

Why does bash execute 2 instances of my script when using a pipe inside of $()

Here is my bash script:

#!/bin/bash

$(find / -name "foo" | grep "bar")

Here is what ps has as output:

$ ps fx
PID TTY      STAT   TIME COMMAND
2690 ?        Sl     1:04 gnome-terminal
5903 pts/8    Ss     0:00  \_ bash
7003 pts/8    S      0:00      \_ bash -x ./test_script.sh
7004 pts/8    S      0:00      |   \_ bash -x ./test_script.sh
7005 pts/8    S      0:00      |       \_ find / -name foo
7006 pts/8    S      0:00      |       \_ grep bar

$ ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000      7003  0.0  0.0   5172  1108 pts/8    S    16:23   0:00 bash -x ./test_script.sh
1000      7004  0.0  0.0   5172   520 pts/8    S    16:23   0:00 bash -x ./test_script.sh
1000      7005  0.7  0.0   4720  1176 pts/8    S    16:23   0:00 find / -name foo
1000      7006  0.0  0.0   4368   824 pts/8    S    16:23   0:00 grep bar

As you can see there are 2 instances of my script being executed, can anyone tell me what exactly bash is doing here? Specifically why are there 2 instances of my script being executed and is there a better way of doing this?

Thanks

Upvotes: 1

Views: 216

Answers (1)

FatalError
FatalError

Reputation: 54561

When you run a subshell (the $(...) part) bash uses the fork() system call which creates a copy of the calling process (where your subshell commands will be executed). Your script isn't being run again, but rather the command line is just inherited from the parent here since there is no exec. In the child shell bash sets up the pipeline, which is why you see find and grep as its children.

Upvotes: 5

Related Questions