A LINE_SET is one or more lines. Append LINE_SET to FILE if it does not exist in
FILE. If no LINE_SET argument is given, read lines from stdin, and treat each
-as a single LINE_SET. Appended text is output to the terminal.
+as a single LINE_SET. Appended text is output to the terminal. Duplicate
+LINE_SETs are treated the same.
- -s don't try to use sudo when it would help us read or write the file
- -- stop processing arguments
- --help display this message"
+ -- stop processing arguments
+ [-h|--help] display this message"
- local readsudo writesudo x strings string content
- local dosudo=true
while true; do
- if [[ $1 == --help ]]; then
+ if [[ $1 == --help || $1 == -h ]]; then
echo "$help"
return
- elif [[ $1 == -s ]]; then
- dosudo=false
- shift
elif [[ $1 == -- ]]; then
shift
break
local file="$1"
shift
- local file_exists=false
+ local new_file=true
if [[ -e $file ]]; then
- file_exists=true
- [[ -r $file ]] || readsudo=sudo
- [[ -w $file ]] || writesudo=sudo
+ new_file=false
else
local dir="$(dirname "$file")"
- if [[ -d $dir ]]; then
- [[ ! -w $dir ]] && writesudo=sudo
- else
+ if [[ ! -d $dir ]]; then
echo "appendu error: $dir does not exist"
return 1
fi
fi
- if ! $dosudo; then
- readsudo=
- writesudo=
+ if ! $new_file; then
+ if [[ ! -r $file ]]; then
+ echo "appendu error: cannot read or write $file"
+ return 1
+ fi
+ if [[ ! -w $file ]]; then
+ echo "appendu error: cannot read or write $file"
+ return 1
+ fi
fi
if (( $# == 0 )); then
strings=( "$@" )
fi
- if $file_exists; then
- # fix files with no newline at the end.
- # the following command won't work right on them.
- # e = run script, $a\ means append following text, but there is none,
- # so sed only does what it always does when it was supposed to modify a file,
- # which is append a newline if there was none.
- sed -ie '$a\' "$file"
- # command substitution removes any trailing newlines, so we have to add
- # a non-newline ending, we randomly chose "b", then remove it.
- content=$($readsudo cat "$file"; echo b) content=${content%b}
-
- # we aren't using regex because we want to match strings,
- # but we also want our match to start at the beginning of a line,
- # or the beginning of the file, and to end at a line ending.
- # So we do some slick bash to match this.
- local start="?(*
+ # fix files with no newline at the end.
+ # the following command won't work right on them otherwise.
+ # e = run script, $a\ means append following text, but there is none,
+ # so sed only does what it always does when it was supposed to modify a file,
+ # which is append a newline if there was none.
+ sed -ie '$a\' "$file"
+ # command substitution removes any trailing newlines, so we have to add
+ # a non-newline ending, we randomly chose "b", then remove it.
+ content=$(cat "$file"; echo b) content=${content%b}
+
+ # we aren't using regex because we want to match strings,
+ # but we also want our match to start at the beginning of a line,
+ # or the beginning of the file, and to end at a line ending.
+ # So we do some slick bash to match this.
+ local start="?(*
)"
- local end="
+ local end="
*"
- for string in "${strings[@]}"; do
- [[ $content != $start"$string"$end ]] && $writesudo tee -a "$file"<<<"$string"
- done
- else
- for string in "${strings[@]}"; do
- $writesudo tee -a "$file"<<<"${strings[@]}"
- done
- fi
+ local return_code
+ for string in "${strings[@]}"; do
+ if $new_file || [[ $content != $start"$string"$end ]]; then
+ if ! tee -a "$file"<<<"$string"; then
+ return_code=$?
+ echo "appendu error: error writing to $file"
+ return $return_code
+ fi
+ fi
+ done
return 0
}
appendu "$@"
A LINE_SET is one or more lines. Append LINE_SET to FILE if it does not exist in
FILE. If no LINE_SET argument is given, read lines from stdin, and treat each
-as a single LINE_SET. Appended text is output to the terminal.
+as a single LINE_SET. Appended text is output to the terminal. Duplicate
+LINE_SETs are treated the same.
- -s don't try to use sudo when it would help us read or write the file
- -- stop processing arguments
- --help display this message"
+ -- stop processing arguments
+ [-h|--help] display this message"
- local readsudo writesudo x strings string content
- local dosudo=true
while true; do
- if [[ $1 == --help ]]; then
+ if [[ $1 == --help || $1 == -h ]]; then
echo "$help"
return
- elif [[ $1 == -s ]]; then
- dosudo=false
- shift
elif [[ $1 == -- ]]; then
shift
break
local file="$1"
shift
- local file_exists=false
+ local new_file=true
if [[ -e $file ]]; then
- file_exists=true
- [[ -r $file ]] || readsudo=sudo
- [[ -w $file ]] || writesudo=sudo
+ new_file=false
else
local dir="$(dirname "$file")"
- if [[ -d $dir ]]; then
- [[ ! -w $dir ]] && writesudo=sudo
- else
+ if [[ ! -d $dir ]]; then
echo "appendu error: $dir does not exist"
return 1
fi
fi
- if ! $dosudo; then
- readsudo=
- writesudo=
+ if ! $new_file; then
+ if [[ ! -r $file ]]; then
+ echo "appendu error: cannot read or write $file"
+ return 1
+ fi
+ if [[ ! -w $file ]]; then
+ echo "appendu error: cannot read or write $file"
+ return 1
+ fi
fi
if (( $# == 0 )); then
strings=( "$@" )
fi
- if $file_exists; then
- # fix files with no newline at the end.
- # the following command won't work right on them.
- # e = run script, $a\ means append following text, but there is none,
- # so sed only does what it always does when it was supposed to modify a file,
- # which is append a newline if there was none.
- sed -ie '$a\' "$file"
- # command substitution removes any trailing newlines, so we have to add
- # a non-newline ending, we randomly chose "b", then remove it.
- content=$($readsudo cat "$file"; echo b) content=${content%b}
-
- # we aren't using regex because we want to match strings,
- # but we also want our match to start at the beginning of a line,
- # or the beginning of the file, and to end at a line ending.
- # So we do some slick bash to match this.
- local start="?(*
+ # fix files with no newline at the end.
+ # the following command won't work right on them otherwise.
+ # e = run script, $a\ means append following text, but there is none,
+ # so sed only does what it always does when it was supposed to modify a file,
+ # which is append a newline if there was none.
+ sed -ie '$a\' "$file"
+ # command substitution removes any trailing newlines, so we have to add
+ # a non-newline ending, we randomly chose "b", then remove it.
+ content=$(cat "$file"; echo b) content=${content%b}
+
+ # we aren't using regex because we want to match strings,
+ # but we also want our match to start at the beginning of a line,
+ # or the beginning of the file, and to end at a line ending.
+ # So we do some slick bash to match this.
+ local start="?(*
)"
- local end="
+ local end="
*"
- for string in "${strings[@]}"; do
- [[ $content != $start"$string"$end ]] && $writesudo tee -a "$file"<<<"$string"
- done
- else
- for string in "${strings[@]}"; do
- $writesudo tee -a "$file"<<<"${strings[@]}"
- done
- fi
+ local return_code
+ for string in "${strings[@]}"; do
+ if $new_file || [[ $content != $start"$string"$end ]]; then
+ if ! tee -a "$file"<<<"$string"; then
+ return_code=$?
+ echo "appendu error: error writing to $file"
+ return $return_code
+ fi
+ fi
+ done
return 0
}