Skip to contentSkip to conversation

/bin/dash -c != /bin/bash -c with pgrep

DISCUSSION Richard Retanubun 2 participants 5 messages Jan 24, 2012

lore
Share & tools
lore
#0 lore raw

Hello,

my dash version is 0.5.5.1-7.4 (from debian/stable I believe)

I ran these two commands on a system where atftpd is not running and I am getting different results

/bin/dash -c "pgrep -f /usr/sbin/atftpd"; echo $?
-vs-
/bin/bash -c "pgrep -f /usr/sbin/atftpd"; echo $?

The dash version returns the PID of the grep itself and thus always succeeds. The bash version works as expected.

Sorry if this is an old bug that is already fixed...
Has it been reported? (and fixed?) I saw a patch about the "-c" mode in but it was reverted...

Signature · 1 line
Richard Retanubun
#1 lore raw

Hi Richard,

Quoted 6 lines · Richard Retanubun

/bin/dash -c "pgrep -f /usr/sbin/atftpd"; echo $?
-vs-
/bin/bash -c "pgrep -f /usr/sbin/atftpd"; echo $?

The dash version returns the PID of the grep itself and thus always succeeds. The bash version works as expected.

As the pgrep(1) manual explains, the running pgrep or pkill process will never report itself as a match. However, when running pgrep through dash, it reports the process id of the shell executing pgrep, while the bash version and recent dash versions optimize "sh -c 'single command'" to

sh -c 'exec pgrep -f /usr/sbin/atftpd'

so there is no shell process left to report.

If that "exec" is specified explicitly, the result is the same in both shells.

Hope that helps,
Jonathan

#2 lore raw
Quoted 19 lines · Jonathan Nieder

Hi Richard,

Quoted 6 lines · Richard Retanubun

/bin/dash -c "pgrep -f /usr/sbin/atftpd"; echo $?
-vs-
/bin/bash -c "pgrep -f /usr/sbin/atftpd"; echo $?

The dash version returns the PID of the grep itself and thus always succeeds. The bash version works as expected.

As the pgrep(1) manual explains, the running pgrep or pkill process will never report itself as a match. However, when running pgrep through dash, it reports the process id of the shell executing pgrep, while the bash version and recent dash versions optimize "sh -c 'single command'" to

sh -c 'exec pgrep -f /usr/sbin/atftpd'

Quoted 7 lines

so there is no shell process left to report.

If that "exec" is specified explicitly, the result is the same in both shells.

Hope that helps,
Jonathan

It sure does, thanks a lot Jonathan.

As an addendum, I find using "pgrep -x atftpd" in this case also yields the expected output in both shell.

Thanks for your time.

-- RR --

#3 lore raw
Quoted 27 lines · Richard Retanubun
Quoted 19 lines · Jonathan Nieder

Hi Richard,

Quoted 6 lines · Richard Retanubun

/bin/dash -c "pgrep -f /usr/sbin/atftpd"; echo $?
-vs-
/bin/bash -c "pgrep -f /usr/sbin/atftpd"; echo $?

The dash version returns the PID of the grep itself and thus always succeeds. The bash version works as expected.

As the pgrep(1) manual explains, the running pgrep or pkill process will never report itself as a match. However, when running pgrep through dash, it reports the process id of the shell executing pgrep, while the bash version and recent dash versions optimize "sh -c 'single command'" to

sh -c 'exec pgrep -f /usr/sbin/atftpd'

Quoted 7 lines

so there is no shell process left to report.

If that "exec" is specified explicitly, the result is the same in both shells.

Hope that helps,
Jonathan

Quoted 8 lines

It sure does, thanks a lot Jonathan.

As an addendum, I find using "pgrep -x atftpd" in this case also yields the expected output in both shell.

Thanks for your time.

-- RR --

Sorry, one more question to clarify, which "recent dash versions" have the optimization?

Debian changelog from wheezy (0.5.7-2) says this:

0005-SHELL-Disable-sh-c-...diff: back out the optimization
that makes dash -c "script" avoid a fork(). It caused
several packages to fail to build from source (thx Stéphane Glondu, closes: #642922).

So it used to, but does not currently?

-- Richard

#4 lore raw
Quoted 2 lines · Richard Retanubun

Sorry, one more question to clarify, which "recent dash versions" have the optimization?

Upstream versions, or you can grab Debian packaging from the proposed-experimental branch at [1].

Cheers,
Jonathan

[1] git://repo.or.cz/dash/debian/jrn.git