fix bug reading file
[tee-unique] / appendu
diff --git a/appendu b/appendu
index feb58d4ee5b283902f189088d2cae823eeaaf556..d03fb45ad9541bc7c32b17d774a3096ac11192cf 100755 (executable)
--- a/appendu
+++ b/appendu
@@ -9,22 +9,17 @@ Append unique.
 
 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
@@ -42,61 +37,66 @@ as a single LINE_SET. Appended text is output to the terminal.
     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=
-    fi
-    
+
+    local strings line
     if (( $# == 0 )); then
         unset IFS
-        while read -r x; do
-            strings+=( "$x" )
+        while read -r line; do
+            strings+=( "$line" )
         done
     else
         strings=( "$@" )
     fi
 
-    if $file_exists; then
+    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            
         # fix files with no newline at the end.
-        # the following command won't work right on them.
+        # 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=$($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="?(*
+        local content=$(cat "$file"; echo b)
+        content=${content%b}
+    fi
+    
+    # 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 string 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 "$@"