#!/bin/bash # Copyright (C) 2016 Ian Kelling # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cedit() { local help="Usage: [-h|--help ] [-v] [SECTION_NAME] FILE Create/modify a section in a config file Returns 1 if the file is modified by this command, 2 or higher for other problems. The section is #comment delimited. Reads STDIN for the contents of the section. Without SECTION_NAME, it acts on a global unnamed section. cedit is short for config edit. -q Quiet -v Verbose -b Keep backup file -h|--help Help" local s diff name init local file_dir="$(dirname "$file")" local exists=true local verbose=false local backup=false local quiet=false case $1 in -b) backup=true; shift ;; -v) verbose=true; shift ;; -q) quiet=true; shift ;; -h|--help) echo "$help"; return ;; esac if (( $# == 2 )); then name=": $1" shift fi 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. #_#_#" if [[ ! -e $file_dir ]]; then if ! mkdir -p $file_dir; then s=sudo $s mkdir -p $file_dir || return 2 fi fi if [[ ! -e $file ]]; then exists=false if ! $s touch $file; then s=sudo $s touch $file || return 2 fi fi [[ -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" while IFS= read -r line; do tailn=$(( tailn + 1 )) if [[ $line == "$begin" ]]; then in_section=true; break fi printf '%s\n' "$line" >> $file done < "$temp" fi IFS= read -d '' -n 1 -r init if [[ $init ]]; then $s tee -a "$file" >/dev/null <<<"$begin" printf '%s' "$init" | $s tee -a "$file" >/dev/null $s tee -a "$file" >/dev/null $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 echo "New file $file:" cat "$file" fi elif type -t diff &>/dev/null; then diff=$(diff -u "$temp" "$file") ret=$? if (( $ret )) && ! $quiet; then echo "backup of original at $temp" echo diff -u "$temp" "$file": echo "$diff" #elif $debug; then # echo "No changes made to $file" fi else # for systems like openwrt which don't have diff diff=$(cmp "$temp" "$file") ret=$? if $verbose; then echo "$diff" fi fi if ! $backup && $exists; then rm -r "$temp" fi return $ret } cedit "$@"