summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorRong Zhang <i@rong.moe>2026-07-22 01:50:49 +0800
committerNicolas Schier <nsc@kernel.org>2026-08-05 14:52:00 +0200
commita75c339a691be98c62ebbee26198e5720072878f (patch)
tree915c5f42a3866702e2536c1fd8a89a86f57d0663 /scripts
parentdc4ab230d66146cd1f70e257dc773664cfb37a45 (diff)
downloadlinux-a75c339a691be98c62ebbee26198e5720072878f.tar.gz
linux-a75c339a691be98c62ebbee26198e5720072878f.zip
scripts/config: Use in-place editing (-i) in sed portably
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 skip creating a backup file. In fact, major sed implementations have supported `-i' for over a decade. It's really doubtful if anyone would still build 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. Reviewed-by: Nicolas Schier <nsc@kernel.org> Signed-off-by: Rong Zhang <i@rong.moe> Link: https://patch.msgid.link/20260722-config-sed-v2-2-9f2c4b164666@rong.moe Signed-off-by: Nicolas Schier <nsc@kernel.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/config31
1 files changed, 19 insertions, 12 deletions
diff --git a/scripts/config b/scripts/config
index 6582b200967c..32428ea909c2 100755
--- a/scripts/config
+++ b/scripts/config
@@ -71,35 +71,34 @@ 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"
+ SED_EDITED=1
}
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"
+ SED_EDITED=1
}
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"
+ SED_EDITED=1
}
set_var() {
@@ -122,6 +121,14 @@ undef_var() {
txt_delete "^($name=|# $name is not set)" "$FN"
}
+SED_EDITED=0
+on_exit() {
+ if [ "$SED_EDITED" -ge 1 ]; then
+ rm -f "$FN.swp"
+ fi
+}
+trap on_exit EXIT
+
FN=.config
CMDS=()
while [[ $# -gt 0 ]]; do