This code generally works exactly as it is supposed to. I'm learning bash I'm looking for some constructive help that could help me improve my work.
#!/bin/bash
usage()
{
echo "Program for uncompressing tar, gzip, rar archives"
echo "Allowed parametres: --help, --file, --input, --directory"
echo "Examples:"
echo "./uncompress.sh --file firstFile secondFile"
echo "./uncompress.sh --input inputFile.txt"
echo "./uncompress.sh --directory /home/"
}
uncompress_file()
{
if [ -f 1ドル ]
then
temp1=`file 1ドル | cut -d: -f2 | grep tar`
if [ "$temp1" != "" ]
then
echo "1ドル is a tar archive, uncompressing..."
tar xf 1ドル > /dev/null
fi
temp1=`file 1ドル | cut -d: -f2 | grep RAR`
if [ "$temp1" != "" ]
then
echo "1ドル is a rar archive, uncompressing..."
unrar e 1ドル > /dev/null
fi
temp1=`file 1ドル | cut -d: -f2 | grep gzip`
if [ "$temp1" != "" ]
then
echo "1ドル is a gzip archive, uncompressing..."
tar xzf 1ドル > /dev/null
fi
else
echo "1ドル is not a valid file!"
fi
}
uncompress_dir()
{
for file in "1ドル"/*
do
if [ -f $file ]
then
uncompress_file $file
fi
if [ -d $file ]
then
uncompress_dir $file
fi
done
}
if [ "1ドル" = "--help" ]
then
usage
exit
fi
if test $# -lt 2
then echo "What about parametres?" 1>&2
exit 1
fi
param=1ドル;
shift;
if [ "$param" = "--file" ]
then
while [ $# -ne 0 ]
do
uncompress_file 1ドル
shift
done
exit
fi
if [ "$param" = "--input" ]
then
if [ -f 1ドル ]
then
while read line
do
uncompress_file $line
done < 1ドル
else
echo "1ドル is not a valid file"
fi
exit
fi
if [ "$param" = "--directory" ]
then
if [ -d 1ドル ]
then
uncompress_dir 1ドル
else
echo "1ドル is not a valid directory"
fi
exit
fi
echo "wrong parametres!";
2 Answers 2
- Don't use
cut
andgrep
, use parameter substitution and a case statement over the file extension to decide the file type (or use thefile
command if you want to be really clever, but I recommend the former actually) - Don't use
[ "${foo}" != "" ]
, use[ -n "${foo}" ]
- Don't mix
test
and[
, just stick to[
unless you want to write code that looksautoconf
generated - Quote all your variables, especially the ones containing filenames to account for spaces, e.g.
tar xzf "1ドル" > /dev/null
- Don't parse command line options yourself, use
getopts
(orgetopt
, in case you really, really want GNU-style options) - Improve your indentation
-
\$\begingroup\$ But file extension doesn't always match content of the file. How could You deal with it then? This is why I decided to extract desired information with
file
. \$\endgroup\$Grzegorz Piwowarek– Grzegorz Piwowarek2013年05月10日 21:13:41 +00:00Commented May 10, 2013 at 21:13 -
\$\begingroup\$ My thought pattern is that if a file has the "wrong" extension, in many cases you will want to know about that and not silently continue. The decompressor should error with an appropriate message anyway. Or you could e.g. implement a
-g
(for "guess") switch to usefile
instead of the file extension. But as I said, this is a matter of preference; if you want to usefile
, go ahead ;-) As an addition source of inspiration you might want to check theunpack
function that Gentoo'sportage
uses here. \$\endgroup\$Adrian Frühwirth– Adrian Frühwirth2013年05月10日 21:30:08 +00:00Commented May 10, 2013 at 21:30
grep
has a non-zero exit status if it finds no matches. So code like this
temp1=`file 1ドル | cut -d: -f2 | grep tar`
if [ "$temp1" != "" ]
then
echo "1ドル is a tar archive, uncompressing..."
tar xf 1ドル > /dev/null
fi
can be more succinctly written as
# -q causes grep to output nothing; we don't really care what it finds,
# just if it finds *something*
if file 1ドル | cut -d: -f2 | grep -q tar
then
echo "1ドル is a tar archive, uncompressing..."
tar xf "1ドル" > /dev/null
fi
Always quote parameter expansions, as I did above for the call to tar
, just in case the value contains whitespace. It's almost never wrong to do so, and you never know when it might be absolutely necessary.