Explanation: with common shells (sh, bash, zsh at least), the chain command `echo cmd args | $SHELL` leaves an unnecessary shell process, waiting for its child process `cmd` to complete. Whereas `$SHELL -c "cmd args"` only leaves one
process `cmd` in the system.

My guess is that, in the second case, the shell is able to see when there is only one command to execute, and in this case it saves a fork operation. Whereas in the first case, there might be subsequent pending commands to process.

--
Glen Mével
From 99cccee3dcac703c3d26befdc3b9f483c877ac79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Glen=20M=C3=A9vel?= <[email protected]>
Date: Sat, 10 Aug 2019 22:56:52 +0200
Subject: [PATCH] avoid some forks in shell scripts

---
 dmenu_path | 2 +-
 dmenu_run  | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/dmenu_path b/dmenu_path
index 3a7cda7..4ab3045 100755
--- a/dmenu_path
+++ b/dmenu_path
@@ -9,5 +9,5 @@ IFS=:
 if stest -dqr -n "$cache" $PATH; then
 	stest -flx $PATH | sort -u | tee "$cache"
 else
-	cat "$cache"
+	exec cat "$cache"
 fi
diff --git a/dmenu_run b/dmenu_run
index 834ede5..14c0653 100755
--- a/dmenu_run
+++ b/dmenu_run
@@ -1,2 +1,3 @@
 #!/bin/sh
-dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
+cmd="$(dmenu_path | dmenu "$@")"
+${SHELL:-"/bin/sh"} -c "$cmd" &
-- 
2.22.0

Reply via email to