Shell POSIX OpenSSL file decryption script follow-up #1
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
This question is the first follow-up of: Shell POSIX OpenSSL file decryption script
Please read it before you continue reading this. Thank you.
I only have one new problem solved and I would like you to have a look.
That problem being accepting one option -o output_directory
.
I have little idea if I did this the best way, but it works.
The code follows:
#!/bin/sh
bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red=$bold$red
bold_yellow=$bold$yellow
print_usage_and_exit()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
exit 1
print_error_and_exit()
echo "$bold_red$1 Exit code = $2.$nocolor" 1>&2
exit "$2"
while getopts ":o:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h | *)
print_usage_and_exit
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage_and_exit
[ "$#" -gt 1 ] &&
print_error_and_exit "Multiple files are not supported." 2
[ ! -f "$1" ] &&
print_error_and_exit "The given argument is not an existing file." 3
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit "Input file is not readable by you." 4
input_filepath=$(dirname "$input_filename")
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
[ ! -w "$output_directory" ] &&
print_error_and_exit "Destination directory is not writable by you." 5
filename_extracted_from_path=$(basename "$input_filename")
filename_without_enc_extension="$filename_extracted_from_path%.enc"
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
# the file has a different than .enc extension or no extension at all
# what we do now, is that we append .dec extention to the file name
output_filename="$output_directory/$filename_extracted_from_path".dec
else
# the file has the .enc extension
# what we do now, is that we use the file name without .enc extension
output_filename="$output_directory/$filename_without_enc_extension"
fi
[ -f "$output_filename" ] &&
print_error_and_exit "Destination file exists." 6
if ! pv -W "$input_filename" | openssl enc -aes-256-cbc -md sha256 -salt -out "$output_filename" -d 2> /dev/null
then
[ -f "$output_filename" ] && rm "$output_filename"
print_error_and_exit "Decryption failed." 7
else
echo "$bold_yellowDecryption successful.$nocolor"
exit 0
fi
linux aes sh posix openssl
add a comment |Â
up vote
1
down vote
favorite
This question is the first follow-up of: Shell POSIX OpenSSL file decryption script
Please read it before you continue reading this. Thank you.
I only have one new problem solved and I would like you to have a look.
That problem being accepting one option -o output_directory
.
I have little idea if I did this the best way, but it works.
The code follows:
#!/bin/sh
bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red=$bold$red
bold_yellow=$bold$yellow
print_usage_and_exit()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
exit 1
print_error_and_exit()
echo "$bold_red$1 Exit code = $2.$nocolor" 1>&2
exit "$2"
while getopts ":o:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h | *)
print_usage_and_exit
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage_and_exit
[ "$#" -gt 1 ] &&
print_error_and_exit "Multiple files are not supported." 2
[ ! -f "$1" ] &&
print_error_and_exit "The given argument is not an existing file." 3
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit "Input file is not readable by you." 4
input_filepath=$(dirname "$input_filename")
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
[ ! -w "$output_directory" ] &&
print_error_and_exit "Destination directory is not writable by you." 5
filename_extracted_from_path=$(basename "$input_filename")
filename_without_enc_extension="$filename_extracted_from_path%.enc"
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
# the file has a different than .enc extension or no extension at all
# what we do now, is that we append .dec extention to the file name
output_filename="$output_directory/$filename_extracted_from_path".dec
else
# the file has the .enc extension
# what we do now, is that we use the file name without .enc extension
output_filename="$output_directory/$filename_without_enc_extension"
fi
[ -f "$output_filename" ] &&
print_error_and_exit "Destination file exists." 6
if ! pv -W "$input_filename" | openssl enc -aes-256-cbc -md sha256 -salt -out "$output_filename" -d 2> /dev/null
then
[ -f "$output_filename" ] && rm "$output_filename"
print_error_and_exit "Decryption failed." 7
else
echo "$bold_yellowDecryption successful.$nocolor"
exit 0
fi
linux aes sh posix openssl
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
This question is the first follow-up of: Shell POSIX OpenSSL file decryption script
Please read it before you continue reading this. Thank you.
I only have one new problem solved and I would like you to have a look.
That problem being accepting one option -o output_directory
.
I have little idea if I did this the best way, but it works.
The code follows:
#!/bin/sh
bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red=$bold$red
bold_yellow=$bold$yellow
print_usage_and_exit()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
exit 1
print_error_and_exit()
echo "$bold_red$1 Exit code = $2.$nocolor" 1>&2
exit "$2"
while getopts ":o:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h | *)
print_usage_and_exit
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage_and_exit
[ "$#" -gt 1 ] &&
print_error_and_exit "Multiple files are not supported." 2
[ ! -f "$1" ] &&
print_error_and_exit "The given argument is not an existing file." 3
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit "Input file is not readable by you." 4
input_filepath=$(dirname "$input_filename")
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
[ ! -w "$output_directory" ] &&
print_error_and_exit "Destination directory is not writable by you." 5
filename_extracted_from_path=$(basename "$input_filename")
filename_without_enc_extension="$filename_extracted_from_path%.enc"
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
# the file has a different than .enc extension or no extension at all
# what we do now, is that we append .dec extention to the file name
output_filename="$output_directory/$filename_extracted_from_path".dec
else
# the file has the .enc extension
# what we do now, is that we use the file name without .enc extension
output_filename="$output_directory/$filename_without_enc_extension"
fi
[ -f "$output_filename" ] &&
print_error_and_exit "Destination file exists." 6
if ! pv -W "$input_filename" | openssl enc -aes-256-cbc -md sha256 -salt -out "$output_filename" -d 2> /dev/null
then
[ -f "$output_filename" ] && rm "$output_filename"
print_error_and_exit "Decryption failed." 7
else
echo "$bold_yellowDecryption successful.$nocolor"
exit 0
fi
linux aes sh posix openssl
This question is the first follow-up of: Shell POSIX OpenSSL file decryption script
Please read it before you continue reading this. Thank you.
I only have one new problem solved and I would like you to have a look.
That problem being accepting one option -o output_directory
.
I have little idea if I did this the best way, but it works.
The code follows:
#!/bin/sh
bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red=$bold$red
bold_yellow=$bold$yellow
print_usage_and_exit()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
exit 1
print_error_and_exit()
echo "$bold_red$1 Exit code = $2.$nocolor" 1>&2
exit "$2"
while getopts ":o:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h | *)
print_usage_and_exit
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage_and_exit
[ "$#" -gt 1 ] &&
print_error_and_exit "Multiple files are not supported." 2
[ ! -f "$1" ] &&
print_error_and_exit "The given argument is not an existing file." 3
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit "Input file is not readable by you." 4
input_filepath=$(dirname "$input_filename")
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
[ ! -w "$output_directory" ] &&
print_error_and_exit "Destination directory is not writable by you." 5
filename_extracted_from_path=$(basename "$input_filename")
filename_without_enc_extension="$filename_extracted_from_path%.enc"
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
# the file has a different than .enc extension or no extension at all
# what we do now, is that we append .dec extention to the file name
output_filename="$output_directory/$filename_extracted_from_path".dec
else
# the file has the .enc extension
# what we do now, is that we use the file name without .enc extension
output_filename="$output_directory/$filename_without_enc_extension"
fi
[ -f "$output_filename" ] &&
print_error_and_exit "Destination file exists." 6
if ! pv -W "$input_filename" | openssl enc -aes-256-cbc -md sha256 -salt -out "$output_filename" -d 2> /dev/null
then
[ -f "$output_filename" ] && rm "$output_filename"
print_error_and_exit "Decryption failed." 7
else
echo "$bold_yellowDecryption successful.$nocolor"
exit 0
fi
linux aes sh posix openssl
edited Jun 19 at 17:46
200_success
123k14143401
123k14143401
asked Jan 18 at 6:02
Vlastimil
519316
519316
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
Although print_error_and_exit
correctly sends output to standard error and exits with a non-zero status, print_usage_and_exit
outputs to standard out. I recommend explicitly accepting -h
(as your case
implies, but getopts
hasn't been instructed to do), and if the user asks for help, then writing to standard out and returning success, but if the help is provided due to error, then writing to standard error and returning failure:
print_usage()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
while getopts ":ho:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h)
print_usage
exit 0
;;
'?')
print_usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage && exit 1
While we're on error reporting, you might want to consider making the exit code be the first argument to print_error_and_exit
rather than the last. That can make the code easier to read, and it also allows you to pass multiple arguments, just like echo
which it wraps:
print_error_and_exit()
value=$1; shift
echo "$bold_red$* Exit code = $value.$nocolor" 1>&2
exit "$value"
It's good to see that you use tput
to produce the terminal-specific escape codes (if they exist) for highlighting. But it's probably not worth putting them into variables for a single use each. I'd get rid of the variables and just write something like
print_error_and_exit()
value=$1; shift
exec >&2
tput bold
tput setaf 1 # red
echo "$* Exit code = $value."
tput sgr0
exit "$value"
and (in the success branch)
else
tput bold
tput setaf 3 # yellow
echo "Decryption successful."
tput sgr0
exit 0
fi
These tests are probably over-doing it:
[ ! -f "$1" ] &&
print_error_and_exit 3 "The given argument is not an existing file."
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit 4 "Input file is not readable by you."
Unless there's a good reason we can't accept input from a pipe or other non-regular file, just skip the -f
test: -r
will fail if its argument doesn't exist. It's also worth including the filename in the message - this is really useful when the user expands a variable into the call, and it doesn't expand to what she expects:
[ -r "$1" ] ||
print_error_and_exit 3 "$1: not a readable file."
If you really feel you need different exit status for non-existent and existing-but-unreadable files (why?), then consider -e
as an alternative to -f
.
We should check whether the supplied output directory is actually a directory, before trying to use it:
[ -d "$output_directory" ] ||
print_error_and_exit 4 "$output_directory: not a directory."
[ -w "$output_directory" ] ||
print_error_and_exit 5 "Destination directory is not writeable by you."
A shorter way to write this:
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
is to use parameter substitution with -
modifier:
output_directory="$given_output_directory:-$input_filepath"
I think a case
helps with matching filename patterns here:
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
I'd write that block as:
filename_extracted_from_path=$(basename "$input_filename")
# Strip .enc suffix from name if it has one, else add .dec suffix
case "$filename_extracted_from_path" in
*.enc)
output_filename="$filename_extracted_from_path%.enc"
;;
*)
output_filename="$filename_extracted_from_path".dec
;;
esac
output_filename="$output_directory/$output_filename"
Note that there's no longer a need for $filename_without_enc_extension
.
You definitely need to replace this -f
with -e
:
[ -f "$output_filename" ] &&
print_error_and_exit 6 "Destination file exists."
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Although print_error_and_exit
correctly sends output to standard error and exits with a non-zero status, print_usage_and_exit
outputs to standard out. I recommend explicitly accepting -h
(as your case
implies, but getopts
hasn't been instructed to do), and if the user asks for help, then writing to standard out and returning success, but if the help is provided due to error, then writing to standard error and returning failure:
print_usage()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
while getopts ":ho:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h)
print_usage
exit 0
;;
'?')
print_usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage && exit 1
While we're on error reporting, you might want to consider making the exit code be the first argument to print_error_and_exit
rather than the last. That can make the code easier to read, and it also allows you to pass multiple arguments, just like echo
which it wraps:
print_error_and_exit()
value=$1; shift
echo "$bold_red$* Exit code = $value.$nocolor" 1>&2
exit "$value"
It's good to see that you use tput
to produce the terminal-specific escape codes (if they exist) for highlighting. But it's probably not worth putting them into variables for a single use each. I'd get rid of the variables and just write something like
print_error_and_exit()
value=$1; shift
exec >&2
tput bold
tput setaf 1 # red
echo "$* Exit code = $value."
tput sgr0
exit "$value"
and (in the success branch)
else
tput bold
tput setaf 3 # yellow
echo "Decryption successful."
tput sgr0
exit 0
fi
These tests are probably over-doing it:
[ ! -f "$1" ] &&
print_error_and_exit 3 "The given argument is not an existing file."
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit 4 "Input file is not readable by you."
Unless there's a good reason we can't accept input from a pipe or other non-regular file, just skip the -f
test: -r
will fail if its argument doesn't exist. It's also worth including the filename in the message - this is really useful when the user expands a variable into the call, and it doesn't expand to what she expects:
[ -r "$1" ] ||
print_error_and_exit 3 "$1: not a readable file."
If you really feel you need different exit status for non-existent and existing-but-unreadable files (why?), then consider -e
as an alternative to -f
.
We should check whether the supplied output directory is actually a directory, before trying to use it:
[ -d "$output_directory" ] ||
print_error_and_exit 4 "$output_directory: not a directory."
[ -w "$output_directory" ] ||
print_error_and_exit 5 "Destination directory is not writeable by you."
A shorter way to write this:
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
is to use parameter substitution with -
modifier:
output_directory="$given_output_directory:-$input_filepath"
I think a case
helps with matching filename patterns here:
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
I'd write that block as:
filename_extracted_from_path=$(basename "$input_filename")
# Strip .enc suffix from name if it has one, else add .dec suffix
case "$filename_extracted_from_path" in
*.enc)
output_filename="$filename_extracted_from_path%.enc"
;;
*)
output_filename="$filename_extracted_from_path".dec
;;
esac
output_filename="$output_directory/$output_filename"
Note that there's no longer a need for $filename_without_enc_extension
.
You definitely need to replace this -f
with -e
:
[ -f "$output_filename" ] &&
print_error_and_exit 6 "Destination file exists."
add a comment |Â
up vote
1
down vote
accepted
Although print_error_and_exit
correctly sends output to standard error and exits with a non-zero status, print_usage_and_exit
outputs to standard out. I recommend explicitly accepting -h
(as your case
implies, but getopts
hasn't been instructed to do), and if the user asks for help, then writing to standard out and returning success, but if the help is provided due to error, then writing to standard error and returning failure:
print_usage()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
while getopts ":ho:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h)
print_usage
exit 0
;;
'?')
print_usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage && exit 1
While we're on error reporting, you might want to consider making the exit code be the first argument to print_error_and_exit
rather than the last. That can make the code easier to read, and it also allows you to pass multiple arguments, just like echo
which it wraps:
print_error_and_exit()
value=$1; shift
echo "$bold_red$* Exit code = $value.$nocolor" 1>&2
exit "$value"
It's good to see that you use tput
to produce the terminal-specific escape codes (if they exist) for highlighting. But it's probably not worth putting them into variables for a single use each. I'd get rid of the variables and just write something like
print_error_and_exit()
value=$1; shift
exec >&2
tput bold
tput setaf 1 # red
echo "$* Exit code = $value."
tput sgr0
exit "$value"
and (in the success branch)
else
tput bold
tput setaf 3 # yellow
echo "Decryption successful."
tput sgr0
exit 0
fi
These tests are probably over-doing it:
[ ! -f "$1" ] &&
print_error_and_exit 3 "The given argument is not an existing file."
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit 4 "Input file is not readable by you."
Unless there's a good reason we can't accept input from a pipe or other non-regular file, just skip the -f
test: -r
will fail if its argument doesn't exist. It's also worth including the filename in the message - this is really useful when the user expands a variable into the call, and it doesn't expand to what she expects:
[ -r "$1" ] ||
print_error_and_exit 3 "$1: not a readable file."
If you really feel you need different exit status for non-existent and existing-but-unreadable files (why?), then consider -e
as an alternative to -f
.
We should check whether the supplied output directory is actually a directory, before trying to use it:
[ -d "$output_directory" ] ||
print_error_and_exit 4 "$output_directory: not a directory."
[ -w "$output_directory" ] ||
print_error_and_exit 5 "Destination directory is not writeable by you."
A shorter way to write this:
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
is to use parameter substitution with -
modifier:
output_directory="$given_output_directory:-$input_filepath"
I think a case
helps with matching filename patterns here:
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
I'd write that block as:
filename_extracted_from_path=$(basename "$input_filename")
# Strip .enc suffix from name if it has one, else add .dec suffix
case "$filename_extracted_from_path" in
*.enc)
output_filename="$filename_extracted_from_path%.enc"
;;
*)
output_filename="$filename_extracted_from_path".dec
;;
esac
output_filename="$output_directory/$output_filename"
Note that there's no longer a need for $filename_without_enc_extension
.
You definitely need to replace this -f
with -e
:
[ -f "$output_filename" ] &&
print_error_and_exit 6 "Destination file exists."
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Although print_error_and_exit
correctly sends output to standard error and exits with a non-zero status, print_usage_and_exit
outputs to standard out. I recommend explicitly accepting -h
(as your case
implies, but getopts
hasn't been instructed to do), and if the user asks for help, then writing to standard out and returning success, but if the help is provided due to error, then writing to standard error and returning failure:
print_usage()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
while getopts ":ho:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h)
print_usage
exit 0
;;
'?')
print_usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage && exit 1
While we're on error reporting, you might want to consider making the exit code be the first argument to print_error_and_exit
rather than the last. That can make the code easier to read, and it also allows you to pass multiple arguments, just like echo
which it wraps:
print_error_and_exit()
value=$1; shift
echo "$bold_red$* Exit code = $value.$nocolor" 1>&2
exit "$value"
It's good to see that you use tput
to produce the terminal-specific escape codes (if they exist) for highlighting. But it's probably not worth putting them into variables for a single use each. I'd get rid of the variables and just write something like
print_error_and_exit()
value=$1; shift
exec >&2
tput bold
tput setaf 1 # red
echo "$* Exit code = $value."
tput sgr0
exit "$value"
and (in the success branch)
else
tput bold
tput setaf 3 # yellow
echo "Decryption successful."
tput sgr0
exit 0
fi
These tests are probably over-doing it:
[ ! -f "$1" ] &&
print_error_and_exit 3 "The given argument is not an existing file."
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit 4 "Input file is not readable by you."
Unless there's a good reason we can't accept input from a pipe or other non-regular file, just skip the -f
test: -r
will fail if its argument doesn't exist. It's also worth including the filename in the message - this is really useful when the user expands a variable into the call, and it doesn't expand to what she expects:
[ -r "$1" ] ||
print_error_and_exit 3 "$1: not a readable file."
If you really feel you need different exit status for non-existent and existing-but-unreadable files (why?), then consider -e
as an alternative to -f
.
We should check whether the supplied output directory is actually a directory, before trying to use it:
[ -d "$output_directory" ] ||
print_error_and_exit 4 "$output_directory: not a directory."
[ -w "$output_directory" ] ||
print_error_and_exit 5 "Destination directory is not writeable by you."
A shorter way to write this:
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
is to use parameter substitution with -
modifier:
output_directory="$given_output_directory:-$input_filepath"
I think a case
helps with matching filename patterns here:
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
I'd write that block as:
filename_extracted_from_path=$(basename "$input_filename")
# Strip .enc suffix from name if it has one, else add .dec suffix
case "$filename_extracted_from_path" in
*.enc)
output_filename="$filename_extracted_from_path%.enc"
;;
*)
output_filename="$filename_extracted_from_path".dec
;;
esac
output_filename="$output_directory/$output_filename"
Note that there's no longer a need for $filename_without_enc_extension
.
You definitely need to replace this -f
with -e
:
[ -f "$output_filename" ] &&
print_error_and_exit 6 "Destination file exists."
Although print_error_and_exit
correctly sends output to standard error and exits with a non-zero status, print_usage_and_exit
outputs to standard out. I recommend explicitly accepting -h
(as your case
implies, but getopts
hasn't been instructed to do), and if the user asks for help, then writing to standard out and returning success, but if the help is provided due to error, then writing to standard error and returning failure:
print_usage()
echo "Usage: $0 [-o output_directory] filename_to_decrypt"
while getopts ":ho:" option
do
case "$option" in
o)
given_output_directory=$OPTARG
;;
h)
print_usage
exit 0
;;
'?')
print_usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
[ "$#" -eq 0 ] &&
print_usage && exit 1
While we're on error reporting, you might want to consider making the exit code be the first argument to print_error_and_exit
rather than the last. That can make the code easier to read, and it also allows you to pass multiple arguments, just like echo
which it wraps:
print_error_and_exit()
value=$1; shift
echo "$bold_red$* Exit code = $value.$nocolor" 1>&2
exit "$value"
It's good to see that you use tput
to produce the terminal-specific escape codes (if they exist) for highlighting. But it's probably not worth putting them into variables for a single use each. I'd get rid of the variables and just write something like
print_error_and_exit()
value=$1; shift
exec >&2
tput bold
tput setaf 1 # red
echo "$* Exit code = $value."
tput sgr0
exit "$value"
and (in the success branch)
else
tput bold
tput setaf 3 # yellow
echo "Decryption successful."
tput sgr0
exit 0
fi
These tests are probably over-doing it:
[ ! -f "$1" ] &&
print_error_and_exit 3 "The given argument is not an existing file."
input_filename="$1"
[ ! -r "$input_filename" ] &&
print_error_and_exit 4 "Input file is not readable by you."
Unless there's a good reason we can't accept input from a pipe or other non-regular file, just skip the -f
test: -r
will fail if its argument doesn't exist. It's also worth including the filename in the message - this is really useful when the user expands a variable into the call, and it doesn't expand to what she expects:
[ -r "$1" ] ||
print_error_and_exit 3 "$1: not a readable file."
If you really feel you need different exit status for non-existent and existing-but-unreadable files (why?), then consider -e
as an alternative to -f
.
We should check whether the supplied output directory is actually a directory, before trying to use it:
[ -d "$output_directory" ] ||
print_error_and_exit 4 "$output_directory: not a directory."
[ -w "$output_directory" ] ||
print_error_and_exit 5 "Destination directory is not writeable by you."
A shorter way to write this:
if [ -z $given_output_directory ]
then
output_directory="$input_filepath"
else
output_directory="$given_output_directory"
fi
is to use parameter substitution with -
modifier:
output_directory="$given_output_directory:-$input_filepath"
I think a case
helps with matching filename patterns here:
if [ "$filename_extracted_from_path" = "$filename_without_enc_extension" ]
then
I'd write that block as:
filename_extracted_from_path=$(basename "$input_filename")
# Strip .enc suffix from name if it has one, else add .dec suffix
case "$filename_extracted_from_path" in
*.enc)
output_filename="$filename_extracted_from_path%.enc"
;;
*)
output_filename="$filename_extracted_from_path".dec
;;
esac
output_filename="$output_directory/$output_filename"
Note that there's no longer a need for $filename_without_enc_extension
.
You definitely need to replace this -f
with -e
:
[ -f "$output_filename" ] &&
print_error_and_exit 6 "Destination file exists."
edited Jun 19 at 9:11
answered Jun 19 at 8:31
Toby Speight
17.8k13491
17.8k13491
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185367%2fshell-posix-openssl-file-decryption-script-follow-up-1%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password