strip out sudo wrapping. various bug fixes
authorIan Kelling <ian@iankelling.org>
Mon, 28 Jul 2014 11:57:10 +0000 (04:57 -0700)
committerIan Kelling <ian@iankelling.org>
Mon, 28 Jul 2014 11:57:10 +0000 (04:57 -0700)
appendu
appendu-function

diff --git a/appendu b/appendu
index feb58d4ee5b283902f189088d2cae823eeaaf556..b613353af65fcd5eef8a3fd0c61491f4997ce6d2 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,23 +37,25 @@ 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=
+    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
@@ -70,33 +67,34 @@ as a single LINE_SET. Appended text is output to the terminal.
         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 "$@"
index 6c97f6cb5f57914469c38d54a6445757a34506c0..37c7b1e9635a271cd68b083d0b40794493df4b45 100644 (file)
@@ -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,23 +37,25 @@ 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=
+    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
@@ -70,32 +67,33 @@ as a single LINE_SET. Appended text is output to the terminal.
         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
 }