Bash script in Prey project formatted incorrectly? Nested backtick issue?
I'm a terrible beginner at bash scripting, and am hoping someone can help me out with this issue.
Having a problem with the Prey project standalone scripts. There's a line that's supposed to send an email, and apparently its not formatted correctly.
response=`mailsender -f "$mail_from" -t "$mail_to" -u "$complete_subject" \
-s $smtp_server -a $file_list -o message-file="$trace_file.msg" \
tls=auto username=$smtp_username \
password=\`decrypt \"$smtp_password\"\``
Where mailsender is an alias to Brandon Zehm's PERL sendEmail script, $smtp_passwo开发者_运维知识库rd is a pointless base64 encoding of the password, and decrypt is:
decrypt() {
echo "$1" | openssl enc -base64 -d
}
So can anyone tell me what's wrong with the script? For reference, if I just replace the entire decrypt part with the plaintext password, it works fine. i.e.:
response=`mailsender -f "$mail_from" -t "$mail_to" -u "$complete_subject" \
-s $smtp_server -a $file_list -o message-file="$trace_file.msg" \
tls=auto username=$smtp_username password=actual_password`
The simplest thing to do is avoid backticks, and use $()
instead -- they nest cleanly, with no special escaping needed:
response=$(Documents/Projects/Shell\ Scripting/printargs -f "$mail_from" \
-t "$mail_to" -u "$complete_subject" -s $smtp_server -a $file_list \
-o message-file="$trace_file.msg" tls=auto username=$smtp_username \
password="$(decrypt "$smtp_password")")
I think this script is isomorphic with yours:
decrypt()
{
echo "$1" | tr 'a-z' 'A-Z'
}
xxx=`echo xxx=yyy pass=\`decrypt \"xyz abc\"\``
echo "$xxx"
When run with 'sh -x xxx
' (where 'sh' is 'bash' in disguise):
$ sh -x xxx
+++ decrypt '"xyz' 'abc"'
+++ echo '"xyz'
+++ tr a-z A-Z
++ echo xxx=yyy 'pass="XYZ'
+ xxx='xxx=yyy pass="XYZ'
+ echo 'xxx=yyy pass="XYZ'
xxx=yyy pass="XYZ
$
You can see where there are problems - if you know how to look. The decrypt
command line has two arguments where the intention was to have just one, and the arguments include a double quote before the first and another at the end of the second.
So, in your script, the argument passed to decrypt
includes a pair of double quotes, which probably isn't what you wanted.
If we rewrite the script using the '$(...)
' notation, which nests much more neatly, then we get:
decrypt()
{
echo "$1" | tr 'a-z' 'A-Z'
}
yyy=$(echo zzz=yyy pass=$(decrypt "xyz abc"))
echo "$yyy"
The trace from this looks like:
$ sh -x xxx
+++ decrypt 'xyz abc'
+++ echo 'xyz abc'
+++ tr a-z A-Z
++ echo zzz=yyy pass=XYZ ABC
+ yyy='zzz=yyy pass=XYZ ABC'
+ echo 'zzz=yyy pass=XYZ ABC'
zzz=yyy pass=XYZ ABC
$
I'm one of the guys from Prey. This bug was confimed yesterday and a fix has already been commited.
I do agree that $()
is much easier to read than backticking -- and specially back-backticking --, and actually that's one of the things we're working on (big code refactoring).
Lately I've been working on a Bash framework called Skull which provides a much nicer interface for writing shell scripts. Hopefully Prey 0.6 will be based completely on it, and excessive backticking will be replaced with $()
to make it easier for everyone to read.
精彩评论