[PATCH 2/2] scripts/config: Use in-place editing (-i) in sed portably
From: Rong Zhang
Date: Sat Jun 06 2026 - 18:13:17 EST
The use of in-place editing was removed by commit 83e8b90e1d2c
("scripts/config: use sed's POSIX interface").
Before that, the script used bare `-i' to enable ERE while skipping
creating a backup file. In fact, mojor sed implementations have
supported `-i' for over a decade. It's really doubtful if anyone would
still compile Linux on a Unix system without it. The issue is more about
how we use it:
FreeBSD and macOS disallow bare `-i'. To skip creating a backup, an
empty string ("zero-length extension") must be passed as a separate
argument following `-i'.
GNU and other BSDs accept bare `-i' to skip creating a backup, but
disallow passing a zero-length extension.
That being said, when thinking about it optimistically, using `-i' is
portable as long as a backup is created.
Use in-place editing (-i) in a portable manner by creating a backup file
with a .swp extension (the same name as the current temporary file). The
backup file will be deleted on exit.
A rough benchmark with ~1000 editions showed a 14.4% speedup (5.27s =>
4.51s, GNU sed). The FreeBSD sed showed a similar speedup.
Signed-off-by: Rong Zhang <i@xxxxxxxx>
---
scripts/config | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/scripts/config b/scripts/config
index 1f290372a4ce..6b6db22f5408 100755
--- a/scripts/config
+++ b/scripts/config
@@ -71,35 +71,31 @@ txt_append() {
local anchor="$1"
local insert="$2"
local infile="$3"
- local tmpfile="$infile.swp"
# sed append cmd: 'a\' + newline + text + newline
cmd="$(printf "a\\%b$insert" "\n")"
- sed -E -e "/$anchor/$cmd" "$infile" >"$tmpfile"
- # replace original file with the edited one
- mv "$tmpfile" "$infile"
+ # We don't really need a backup file, but in-place editing with backup
+ # skipped is not portable due to different implementations parsing
+ # arguments in incompatible manners.
+ # Create a backup file anyway to ensure portability. The file will be
+ # deleted on exit.
+ sed -E -i.swp -e "/$anchor/$cmd" "$infile"
}
txt_subst() {
local before="$1"
local after="$2"
local infile="$3"
- local tmpfile="$infile.swp"
- sed -E -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
- # replace original file with the edited one
- mv "$tmpfile" "$infile"
+ sed -E -i.swp -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile"
}
txt_delete() {
local text="$1"
local infile="$2"
- local tmpfile="$infile.swp"
- sed -E -e "/$text/d" "$infile" >"$tmpfile"
- # replace original file with the edited one
- mv "$tmpfile" "$infile"
+ sed -E -i.swp -e "/$text/d" "$infile"
}
set_var() {
@@ -142,6 +138,8 @@ if [ "$1" = "" ] ; then
usage
fi
+trap 'rm -f "$FN.swp"' EXIT
+
MUNGE_CASE=yes
while [ "$1" != "" ] ; do
CMD="$1"
--
2.53.0