mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 10:00:03 -04:00
scripts/config: Use in-place editing (-i) in sed portably
The use of in-place editing was removed by commit 83e8b90e1d
("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>
This commit is contained in:
committed by
Nicolas Schier
parent
dc4ab230d6
commit
a75c339a69
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user