Invert grep of a lot of values no consistent output - linux

I'm currently working on setting up automatized pentest reporting. The scripts I set up perform TLS and other security checks to see if the application is secure in these aspects yes or no. Currently use the testssl.sh application (which can be found here: https://testssl.sh/) to perform these checks. I then output the findings to a csv file and created a script that greps the file in question and based on what is found, he will mention something is wrong or is correct. Seeing as I have performed a check and all values were correct, I apply invert greps to say that whenever the value cannot be found in the file, then he needs to perform a certain action.
At first I thought the script I was working on was working, however, when testing another site, the output generated is not correct. Things that are missing should be mentioned, however, when I invert grep only one term without placing OR statements in between the large amounts of things that need to be checked it seems to work.
I have tried all sorts of grep types to get a constant output, but no luck so far. So far, I have tried the following:
if grep -v -e "NULLciphersnoencryptionnotoffered" -e "AnonymousNULLCiphersnoauthenticationnotoffered" -e "ExportcipherswoADHNULLnotoffered" -e "LOW64BitDESencryptionwoexportnotoffered|" -e "Weak128BitciphersSEEDIDEARC24notoffered" -e "TripleDESCiphersMediumnotoffered" -e "HighencryptionAESCamellianoAEADoffered" -e "StrongencryptionAEADciphersoffered" ./resultaten/tls-cipher-suites-ng.csv; then
echo 'This is wrong' >> ../CH-40-Scans.tex
else
echo 'This is correct.' >> ../CH-40-Scans.tex
fi
What I see is that the above does not show This is wrong, but This is correct, while the following does trigger:
if ! grep -q -i "ipv6enabled" ./resultaten/tls-vulnerabilities-new-def.csv; then
echo '\item This is wrong.' >> ../CH-40-Scans.tex
fi
I already replaced the -e with the | variant, but I am not having luck so far on finding a consistent working method (also tried things as egrep). Is there another way to get this working? I don't mind using things such as Java or PHP or whatever to get this working, so if those are needed to create something consistent that would be fine.
I would gladly hear anything I could try to get a trustworthy working fix.

I don't know what it is you're trying to do but try these:
if awk '/NULLciphersnoencryptionnotoffered/ || \
/AnonymousNULLCiphersnoauthenticationnotoffered/ || \
/StrongencryptionAEADciphersoffered/ { f=1; exit }
END { exit !f }' ./resultaten/tls-cipher-suites-ng.csv; then
echo 'Present'
else
echo 'Absent'
fi
if awk -v RS='^$' '/NULLciphersnoencryptionnotoffered/ && \
/AnonymousNULLCiphersnoauthenticationnotoffered/ && \
/StrongencryptionAEADciphersoffered/ { f=1 }
END { exit !f }' ./resultaten/tls-cipher-suites-ng.csv; then
echo 'Present'
else
echo 'Absent'
fi
The first one will exit success if any of the "strings" are present, the second one will exit success if all of them are present. That second one requires GNU awk for multi-char RS.

This works, and may serve as an example (note I have commented out the redirection to /dev/null)
$> cat script
#!/bin/bash
e1="$1"
e2="$2"
if grep -v -e "$e1" -e "$e2" infile #>/dev/null
then
echo "found at least one line without the string(s)"
else
echo "found NO lines without all the string(s)!"
fi
$> cat infile
nabucco
aida
il trovatore
$> script a b
found NO lines without all the string(s)!
$> script z b
aida
trovatore
found at least one line without the string(s)

Related

How to search for multiple domain names availability using bash?

I'm trying to search for multiple domain names availability with this script but it doesn't work, where's the mistake? thanks
#!/bin/bash
WEB=('madmane1' 'madmane2' 'madmane3' 'madmane4' 'madmane5' 'madmane6' 'madmane7' 'madmane8' 'madmane9')
ELEMENTS=${#WEB[#]}
for (( i=0;i<$ELEMENTS;i++)); do
whois ${WEB[${i}]}$'.com' | egrep -q \
'^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri'
if [ $? -eq 0 ]; then
echo "${WEB[${i}]}$'.com' : available"
fi
done
here's the error:
line 9: ^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri: command not found
Assigning stuff to an array and then wrecking it by assigning it to a string without quoting seems like the main mistake here, though it's not the reason you are getting a syntax error.
You also want to avoid testing ”$?” to see if a command succeeded or not, an anti-pattern
See also Correct Bash and shell script variable capitalization
The reason for the error message seems to be a space after the backslash, so you are escaping the space instead of the newline, and thus the shell (in some sense correctly) parses the next line as a new command.
#!/bin/bash
web=('madmane1' 'madmane2' 'madmane3' 'madmane4' 'madmane5' 'madmane6' 'madmane7' 'madmane8' 'madmane9')
for domain in "${web[#]}"; do
if whois "$domain.com" |
grep -Eq '^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri'
then
echo "$domain.com: available"
fi
done
Going forward, probably try http://shellcheck.net/ before asking for human assistance.
I think I fixed the problem with https://www.shellcheck.net/
here it is now:
#!/bin/bash
WEB=('madmane1' 'madmane2' 'madmane3' 'madmane4' 'madmane5' 'madmane6' 'madmane7' 'madmane8' 'madmane9')
ELEMENTS=${#WEB[#]}
for (( i=0;i<$ELEMENTS;i++)); do
whois "${WEB[${i}]}"$'.com' | grep -E \
'^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri'
if [ $? -eq 0 ]; then
echo "${WEB[${i}]}$'.com' : available"
fi
done

Can I avoid using a FIFO file to join the end of a Bash pipeline to be stored in a variable in the current shell?

I have the following functions:
execIn ()
{
local STORE_INvar="${1}" ; shift
printf -v "${STORE_INvar}" '%s' "$( eval "$#" ; printf %s x ; )"
printf -v "${STORE_INvar}" '%s' "${!STORE_INvar%x}"
}
and
getFifo ()
{
local FIFOfile
FIFOfile="/tmp/diamondLang-FIFO-$$-${RANDOM}"
while [ -e "${FIFOfile}" ]
do
FIFOfile="/tmp/diamondLang-FIFO-$$-${RANDOM}"
done
mkfifo "${FIFOfile}"
echo "${FIFOfile}"
}
I want to store the output of the end of a pipeline into a variable as given to a function at the end of the pipeline, however, the only way I have found to do this that will work in early versions of Bash is to use mkfifo to make a temp fifo file. I was hoping to use file descriptors to avoid having to create temporary files. So, This works, but is not ideal:
Set Up: (before I can do this I need to have assigned a FIFO file to a var that can be used by the rest of the process)
$ FIFOfile="$( getFifo )"
The Pipeline I want to persist:
$ printf '\n\n123\n456\n524\n789\n\n\n' | grep 2 # for e.g.
The action: (I can now add) >${FIFOfile} &
$ printf '\n\n123\n456\n524\n789\n\n\n' | grep 2 >${FIFOfile} &
N.B. The need to background it with & - Problem 1: I get [1] <PID_NO> output to the screen.
The actual persist:
$ execIn SOME_VAR cat - <${FIFOfile}
Problem 2: I get more noise to the screen
[1]+ Done printf '\n\n123\n456\n524\n789\n\n\n' | grep 2 > ${FIFOfile}
Problem 3: I loose the blanks at the start of the stream rather than at the end as I have experienced before.
So, am I doing this the right way? I am sure that there must be a way to avoid the need of a FIFO file that needs cleanup afterwards using file descriptors, but I cannot seem to do this as I cannot assign either side of the problem to a file descriptor that is not attached to a file or a FIFO file.
I can try and resolve the problems with what I have, although to make this work properly I guess I need to pre-establish a pool of FIFO files that can be pulled in to use or else I have a pre-req of establishing this file before the command. So, for many reasons this is far from ideal. If anyone can advise me of a better way you would make my day/week/month/life :)
Thanks in advance...
Process substitution was available in bash from the ancient days. You absolutely do not have a version so ancient as to be unable to use it. Thus, there's no need to use a FIFO at all:
readToVar() { IFS= read -r -d '' "$1"; }
readToVar targetVar < <(printf '\n\n123\n456\n524\n789\n\n\n')
You'll observe that:
printf '%q\n' "$targetVar"
...correctly preserves the leading newlines as well as the trailing ones.
By contrast, in a use case where you can't afford to lose stdin:
readToVar() { IFS= read -r -d '' "$1" <"$2"; }
readToVar targetVar <(printf '\n\n123\n456\n524\n789\n\n\n')
If you really want to pipe to this command, are willing to require a very modern bash, and don't mind being incompatible with job control:
set +m # disable job control
shopt -s lastpipe # in a pipeline, parent shell becomes right-hand side
readToVar() { IFS= read -r -d '' "$1"; }
printf '\n\n123\n456\n524\n789\n\n\n' | grep 2 | readToVar targetVar
The issues you claim to run into with using a FIFO do not actually exist. Put this in a script, and run it:
#!/bin/bash
trap 'rm -rf "$tempdir"' 0 # cleanup on exit
tempdir=$(mktemp -d -t fifodir.XXXXXX)
mkfifo "$tempdir/fifo"
printf '\n\n123\n456\n524\n789\n\n\n' >"$tempdir/fifo" &
IFS= read -r -d '' content <"$tempdir/fifo"
printf '%q\n' "$content" # print content to console
You'll notice that, when run in a script, there is no "noise" printed to the screen, because all that status is explicitly tied to job control, which is disabled by default in scripts.
You'll also notice that both leading and tailing newlines are correctly represented.
One idea, tell me I am crazy, might be to use the !! notation to grab the line just executed, e.g. if there is a command that can terminate a pipeline and stop it actually executing, whilst still as far as the shell is concerned, consider it as a successful execution, I am thinking something like the true command, I could then use !! to grab that line and call my existing function to execute it with process substitution or something. I could then wrap this into an alias, something like: alias streamTo=' | true ; LAST_EXEC="!!" ; myNewCommandVariation <<<' which I think could be used something like: $ cmd1 | cmd2 | myNewCommandVariation THE_VAR_NAME_TO_SET and the <<< from the alias would pass the var name to the command as an arg or stdin, either way, the command would be not at the end of a pipeline. How mad is this idea?
Not a full answer but rather a first point: is there some good reason not using mktemp for creating a new file with a random name? As far as I can see, your function called getFifo() doesn't perform much more.
mktemp -u
will give to you a free new name without creating anything; then you can use mkfifo with this name.

Make SED command work for any variable

deploy.sh
USERNAME="Tom"
PASSWORD="abc123"
FILE="config.conf"
sed -i "s/\PLACEHOLDER_USERNAME/$USERNAME/g" $FILE
sed -i "s/\PLACEHOLDER_PASSWORD/$PASSWORD/g" $FILE
config.conf
deloy="PLACEHOLDER_USERNAME"
pass="PLACEHOLDER_PASSWORD"
This file puts my variables defined in deploy into my config file. I can't source the file so I want put my variables in this way.
Question
I want a command that is generic to work for all placeholder variables using some sort of while loop rather than needing one command per variable. This means any term starting with placeholder_ in the file will try to be replaced with the value of the variable defined already in deploy.sh
All variables should be set and not empty. I guess if there is the ability to print a warning if it can't find the variable that would be good but it isn't mandatory for this.
Basically, use shell code to write a sed script and then use sed -i .bak -f sed.script config.conf to apply it:
trap "rm -f sed.script; exit 1" 0 1 2 3 13 15
for var in USERNAME PASSWORD
do
echo "s/PLACEHOLDER_$var/${!var}/"
done > sed.script
sed -i .bak -f sed.script config.conf
rm -f sed.script
trap 0
The main 'tricks' here are:
knowing that ${!var} expands to the value of the variable named by $var, and
knowing that sed will take a script full of commands via -f sed.script, and
knowing how to use trap to ensure temporary files are cleaned up.
You could also use sed -e "s/.../.../" -e "s/.../.../" -i .bak config.conf too, but the script file is easier, I think, especially if you have more than 2 values to substitute. If you want to go down this route, use a bash array to hold the arguments to sed. A more careful script would use at least $$ in the script file name, or use mktemp to create the temporary file.
Revised answer
The trouble is, although much closer to being generic, it is still not generic since I have to manually put in what variables I want to change. Can it not be more like "for each placeholder_, find the variable in deploy.sh and add that variable, so it can work for any number of variables.
So, find what the variables are in the configuration file, then apply the techniques of the previous answer to solve that problem:
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
for file in "$#"
do
for var in $(sed 's/.*PLACEHOLDER_\([A-Z0-9_]*\).*/\1/' "$file")
do
value="${!var}"
[ -z "$value" ] && { echo "$0: variable $var not set for $file" >&2; exit 1; }
echo "s/PLACEHOLDER_$var/$value/"
done > $tmp
sed -i .bak -f $tmp "$file"
rm -f $tmp
done
trap 0
This code still pulls the values from the environment. You need to clarify what is required if you want to extract the settings from the shell script, but it can be done — the script will have to be sufficiently self-aware to find its source so it can search it for the names. But the basics are in this answer; the rest is a question of tinkering until it does what you need.
#!/bin/ksh
TemplateFile=$1
SourceData=$2
(sed 's/.*/#V0r:PLACEHOLDER_&:r0V#/' ${SourceData}; cat ${TemplateFile}) | sed -n "
s/$/²/
H
$ {
x
s/^\(\n *\)*//
# also reset t flag
t varxs
:varxs
s/^#V0r:\([a-zA-Z0-9_]\{1,\}\)=\([^²]*\):r0V#²\(\n.*\)\"\1\"/#V0r:\1=\2:r0V#²\3\2/
t varxs
# clean the line when no more occurance in text
s/^[^²]*:r0V#²\n//
# and next
t varxs
# clean the marker
s/²\(\n\)/\1/g
s/²$//
# display the result
p
}
"
call like this: YourScript.ksh YourTemplateFile YourDataSourceFile where:
YourTemplateFile is the file that contain the structure with generic value like deloy="PLACEHOLDER_USERNAME"
YourDataSourceFile is the file that contain all the peer Generic value = specific value like USERNAME="Tom"

How to check if sed has changed a file

I am trying to find a clever way to figure out if the file passed to sed has been altered successfully or not.
Basically, I want to know if the file has been changed or not without having to look at the file modification date.
The reason why I need this is because I need to do some extra stuff if sed has successfully replaced a pattern.
I currently have:
grep -q $pattern $filename
if [ $? -eq 0 ]
then
sed -i s:$pattern:$new_pattern: $filename
# DO SOME OTHER STUFF HERE
else
# DO SOME OTHER STUFF HERE
fi
The above code is a bit expensive and I would love to be able to use some hacks here.
A bit late to the party but for the benefit of others, I found the 'w' flag to be exactly what I was looking for.
sed -i "s/$pattern/$new_pattern/w changelog.txt" "$filename"
if [ -s changelog.txt ]; then
# CHANGES MADE, DO SOME STUFF HERE
else
# NO CHANGES MADE, DO SOME OTHER STUFF HERE
fi
changelog.txt will contain each change (ie the changed text) on it's own line. If there were no changes, changelog.txt will be zero bytes.
A really helpful sed resource (and where I found this info) is http://www.grymoire.com/Unix/Sed.html.
I believe you may find these GNU sed extensions useful
t label
If a s/// has done a successful substitution since the last input line
was read and since the last t or T command, then branch to label; if
label is omitted, branch to end of script.
and
q [exit-code]
Immediately quit the sed script without processing any more input, except
that if auto-print is not disabled the current pattern space will be printed.
The exit code argument is a GNU extension.
It seems like exactly what are you looking for.
This might work for you (GNU sed):
sed -i.bak '/'"$old_pattern"'/{s//'"$new_pattern"'/;h};${x;/./{x;q1};x}' file || echo changed
Explanation:
/'"$old_pattern"'/{s//'"$new_pattern"'/;h} if the pattern space (PS) contains the old pattern, replace it by the new pattern and copy the PS to the hold space (HS).
${x;/./{x;q1};x} on encountering the last line, swap to the HS and test it for the presence of any string. If a string is found in the HS (i.e. a substitution has taken place) swap back to the original PS and exit using the exit code of 1, otherwise swap back to the original PS and exit with the exit code of 0 (the default).
You can diff the original file with the sed output to see if it changed:
sed -i.bak s:$pattern:$new_pattern: "$filename"
if ! diff "$filename" "$filename.bak" &> /dev/null; then
echo "changed"
else
echo "not changed"
fi
rm "$filename.bak"
You could use awk instead:
awk '$0 ~ p { gsub(p, r); t=1} 1 END{ exit (!t) }' p="$pattern" r="$repl"
I'm ignoring the -i feature: you can use the shell do do redirections as necessary.
Sigh. Many comments below asking for basic tutorial on the shell. You can use the above command as follows:
if awk '$0 ~ p { gsub(p, r); t=1} 1 END{ exit (!t) }' \
p="$pattern" r="$repl" "$filename" > "${filename}.new"; then
cat "${filename}.new" > "${filename}"
# DO SOME OTHER STUFF HERE
else
# DO SOME OTHER STUFF HERE
fi
It is not clear to me if "DO SOME OTHER STUFF HERE" is the same in each case. Any similar code in the two blocks should be refactored accordingly.
In macos I just do it as follows:
changes=""
changes+=$(sed -i '' "s/$to_replace/$replacement/g w /dev/stdout" "$f")
if [ "$changes" != "" ]; then
echo "CHANGED!"
fi
I checked, and this is faster than md5, cksum and sha comparisons
I know it is a old question and using awk instead of sed is perhaps the best idea, but if one wants to stick with sed, an idea is to use the -w flag. The file argument to the w flag only contains the lines with a match. So, we only need to check that it is not empty.
perl -sple '$replaced++ if s/$from/$to/g;
END{if($replaced != 0){ print "[Info]: $replaced replacement done in $ARGV(from/to)($from/$to)"}
else {print "[Warning]: 0 replacement done in $ARGV(from/to)($from/$to)"}}' -- -from="FROM_STRING" -to="$DESIRED_STRING" </file/name>
Example:
The command will produce the following output, stating the number of changes made/file.
perl -sple '$replaced++ if s/$from/$to/g;
END{if($replaced != 0){ print "[Info]: $replaced replacement done in $ARGV(from/to)($from/$to)"}
else {print "[Warning]: 0 replacement done in $ARGV(from/to)($from/$to)"}}' -- -from="timeout" -to="TIMEOUT" *
[Info]: 5 replacement done in main.yml(from/to)(timeout/TIMEOUT)
[Info]: 1 replacement done in task/main.yml(from/to)(timeout/TIMEOUT)
[Info]: 4 replacement done in defaults/main.yml(from/to)(timeout/TIMEOUT)
[Warning]: 0 replacement done in vars/main.yml(from/to)(timeout/TIMEOUT)
Note: I have removed -i from the above command , so it will not update the files for the people who are just trying out the command. If you want to enable in-place replacements in the file add -i after perl in above command.
check if sed has changed MANY files
recursive replace of all files in one directory
produce a list of all modified files
workaround with two stages: match + replace
g='hello.*world'
s='s/hello.*world/bye world/g;'
d='./' # directory of input files
o='modified-files.txt'
grep -r -l -Z -E "$g" "$d" | tee "$o" | xargs -0 sed -i "$s"
the file paths in $o are zero-delimited
$ echo hi > abc.txt
$ sed "s/hi/bye/g; t; q1;" -i abc.txt && (echo "Changed") || (echo "Failed")
Changed
$ sed "s/hi/bye/g; t; q1;" -i abc.txt && (echo "Changed") || (echo "Failed")
Failed
https://askubuntu.com/questions/1036912/how-do-i-get-the-exit-status-when-using-the-sed-command/1036918#1036918
Don't use sed to tell if it has changed a file; instead, use grep to tell if it is going to change a file, then use sed to actually change the file. Notice the single line of sed usage at the very end of the Bash function below:
# Usage: `gs_replace_str "regex_search_pattern" "replacement_string" "file_path"`
gs_replace_str() {
REGEX_SEARCH="$1"
REPLACEMENT_STR="$2"
FILENAME="$3"
num_lines_matched=$(grep -c -E "$REGEX_SEARCH" "$FILENAME")
# Count number of matches, NOT lines (`grep -c` counts lines),
# in case there are multiple matches per line; see:
# https://superuser.com/questions/339522/counting-total-number-of-matches-with-grep-instead-of-just-how-many-lines-match/339523#339523
num_matches=$(grep -o -E "$REGEX_SEARCH" "$FILENAME" | wc -l)
# If num_matches > 0
if [ "$num_matches" -gt 0 ]; then
echo -e "\n${num_matches} matches found on ${num_lines_matched} lines in file"\
"\"${FILENAME}\":"
# Now show these exact matches with their corresponding line 'n'umbers in the file
grep -n --color=always -E "$REGEX_SEARCH" "$FILENAME"
# Now actually DO the string replacing on the files 'i'n place using the `sed`
# 's'tream 'ed'itor!
sed -i "s|${REGEX_SEARCH}|${REPLACEMENT_STR}|g" "$FILENAME"
fi
}
Place that in your ~/.bashrc file, for instance. Close and reopen your terminal and then use it.
Usage:
gs_replace_str "regex_search_pattern" "replacement_string" "file_path"
Example: replace do with bo so that "doing" becomes "boing" (I know, we should be fixing spelling errors not creating them :) ):
$ gs_replace_str "do" "bo" test_folder/test2.txt
9 matches found on 6 lines in file "test_folder/test2.txt":
1:hey how are you doing today
2:hey how are you doing today
3:hey how are you doing today
4:hey how are you doing today hey how are you doing today hey how are you doing today hey how are you doing today
5:hey how are you doing today
6:hey how are you doing today?
$SHLVL:3
Screenshot of the output:
References:
https://superuser.com/questions/339522/counting-total-number-of-matches-with-grep-instead-of-just-how-many-lines-match/339523#339523
https://unix.stackexchange.com/questions/112023/how-can-i-replace-a-string-in-a-files/580328#580328

Shell scripts for Meld Nautilus context menu

Beyond Compare provides "Select for compare" and "Compare to Selected" by using two nautilus scripts (stored in /home/user/.gnome2/nautilus-scripts).
Script 1: Select for compare
#!/bin/sh
quoted=$(echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | awk 'BEGIN { FS = "\n" } { printf "\"%s\" ", $1 }' | sed -e s#\"\"##)
echo "$quoted" > $HOME/.beyondcompare/nautilus
Script 2: Compare to Selected
#!/bin/sh
arg2=$(cat $HOME/.beyondcompare/nautilus)
arg1=$(echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | awk 'BEGIN { FS = "\n" } { printf "\"%s\" ", $1 }' | sed -e s#\"\"##)
bcompare $arg1 $arg2
I am trying to do similar scripts for Meld, but it is not working.
I am not familiar with shell scripts. Can anyone help me understand this:
quoted=$(echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | awk 'BEGIN { FS = "\n" } { printf "\"%s\" ", $1 }' | sed -e s#\"\"##)
so that I can adapt to meld.
If you are not rolling your own solution for the sake of learning, I would suggest installing the diff-ext extension to nautilus. It is cross platform and if you are running Debian/Ubuntu installing it should be as simple as sudo apt-get install diff-ext.
Check out some screenshots here - http://diff-ext.sourceforge.net/screenshots.shtml
The quoted=$( ...) assigns whatever output there is to the variable named quoted, and can be used later in the script as $quoted OR ${quoted} OR "${quoted}" OR "$quoted"
The '|' char is called a 'pipe' in unix/linux and it connects the output of the preceding command to feed into the following command.
So you just take the script apart 1 piece at a time and see what it does,
quoted=$(
# I would execute below by itself first
echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
# then add on this piped program to see how data gets transformed
| awk 'BEGIN { FS = "\n" } { printf "\"%s\" ", $1 }'
# then add this
| sed -e s#\"\"##
# the capturing of the output to the var 'quoted' is the final step of code
)
# you **cannot** copy paste this whole block of code and expect it to work ;-)
I don't know what is supposed to be in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS, so it is hard to show you here. AND, that variable is not defined in any of the code you specify here, so you may only get a blank line when you echo its value. Be prepared to do some research on how that value get set AND what are the correct values.
Also I notice that your code is 'prefixed' as #!/bin/sh. If it is truly /bin/sh then command substitution like quoted=$(....) will not work and should generate an error message. Persumably your system is really using bash for /bin/sh. You can eliminate any possible confusion in the future (when changing to a system where /bin/sh = bourne shell), by changing the 'shebang' to #! /bin/bash.
I hope this helps.
I just discovered diff-ext thanks to this post, excellent!
The first try I did failed: by default diff-ext does not handle backup files (*~ and *.bak). To enable this, run:
$ diff-ext-setup
and in the Mime types pane, check application/x-trash.
Now you can compare a file and its backup.

Resources