#!/bin/bash
-# Copyright (C) 2016 Ian Kelling
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
cedit() {
local help="Usage: [-h|--help ] [-v] [SECTION_NAME] FILE
-Create/modify a section in a config file
+Create/modify a comment-delimited section in a config file
Returns 1 if the file is modified by this command, 2 or higher
for other problems.
section. Without SECTION_NAME, it acts on a global unnamed
section. cedit is short for config edit.
--v Verbose
-b Keep backup file
+-e Exit 0 on modified file.
+-s Silent. Quiet and exit 0 on modified file.
+-q Quiet
+-v Verbose
-h|--help Help"
- local s diff name init
- local file_dir="$(dirname "$file")"
- local exists=true
- local verbose=false
- local backup=false
+ local s diff name init file_dir exists verbose backup quiet silent
+ file_dir="$(dirname "$file")"
+ exists=true
+ verbose=false
+ backup=false
+ quiet=false
+ silent=false
+ exit_status=true
case $1 in
-b) backup=true; shift ;;
+ -e) exit_status=false; shift ;;
+ -s) quiet=true; silent=true; exit_status=false; shift ;;
+ -q) quiet=true; shift ;;
-v) verbose=true; shift ;;
-h|--help) echo "$help"; return ;;
esac
local file="$1"
local file_name="${file##*/}"
- local begin="#_#_# start delimiter of cedit section$name. do not modify. #_#_#"
- local end="#_#_# end delimiter of cedit section$name. do not modify. #_#_#"
+ local comment
+ comment="#_#_#"
+
+ # bind zone files use ; for comments yes, a little hacky detection.
+ if [[ $file_name == db.* ]]; then
+ comment=";;_;_;"
+ fi
+ local begin="$comment start delimiter of cedit section$name. do not modify. $comment"
+ local end="$comment end delimiter of cedit section$name. do not modify. $comment"
if [[ ! -e $file_dir ]]; then
if ! mkdir -p $file_dir; then
[[ -w $file ]] || s=sudo
+ local in_section=false
if $exists; then
+ local tailn=1
local temp="$(mktemp -d)/$file_name"
cp "$file" "$temp"
cp /dev/null "$file"
- local in_section=false
while IFS= read -r line; do
- if [[ $line == $begin ]]; then
+ tailn=$(( tailn + 1 ))
+ if [[ $line == "$begin" ]]; then
in_section=true;
+ break
fi
- if ! $in_section; then
- printf '%s\n' "$line" >> $file
- fi
- if [[ $line == $end ]]; then
- in_section=false;
- fi
+ printf '%s\n' "$line" >> $file
done < "$temp"
fi
$s tee -a "$file" >/dev/null <<<"$end"
fi
+ if $exists && $in_section; then
+ while IFS= read -r line; do
+ if [[ $line == "$begin" ]]; then
+ in_section=true;
+ fi
+ if ! $in_section; then
+ printf '%s\n' "$line" >> $file
+ fi
+ if [[ $line == $end ]]; then
+ in_section=false;
+ fi
+ done < <(tail -n +$tailn "$temp")
+ fi
+
+
if ! $exists; then
ret=1
if $verbose; then
elif type -t diff &>/dev/null; then
diff=$(diff -u "$temp" "$file")
ret=$?
- if (( $ret )); then
+ if (( $ret )) && ! $quiet; then
echo "backup of original at $temp"
echo diff -u "$temp" "$file":
echo "$diff"
- elif $verbose; then
- echo "No changes made to $file"
+ #elif $debug; then
+ # echo "No changes made to $file"
fi
else
# for systems like openwrt which don't have diff
echo "$diff"
fi
fi
- if ! $backup; then
- rm -r $"$temp"
+ if ! $backup && $exists; then
+ rm -r "$temp"
+ fi
+ if ! $exit_status; then
+ case $ret in
+ 0|1) return 0 ;;
+ *) return $ret ;;
+ esac
+ else
+ return $ret
fi
- return $ret
}
cedit "$@"