Reputation: 21
As of the moment I'm making a bash script that unpacks tarballs to install them. I'm on the part that unpacks the tarballs into a directoy. This is the script:
#!/Bin/bash/
# This program auto-installs tarballs for you.
# I designed this for Linux noobies who don't
# know how to install tarballs. Or, it's for
# people like me who are just lazy, and don't
# want to put in the commands ourselves.
echo "AutoTar v1.1"
echo "Gnu GPL v2.1"
read -p "Path to tarball:" pathname
cd "${pathname/#~/$HOME}"
ls $pathname
read -p "Please enter the file you wish to complile..." filename
if [-a $filename] == false
then
echo "File does not exist! Exiting the program."
if [[ ${filename -d} ==*.tar.gz ]]
then
tar -xzf $filename
done
else if
[[ ${filename -d} ==*.tgz ]]
then
tar -xzf $filename
done
else if
[[ ${filename -d} ==*.tar.bz2 ]]
then
tar -xjf $filename
done
ls $pathname
echo -n "Please enter the directory of the file you have just unpacked...:"
read directory
cd $directory
What I need to do is use an if statement in order to detect the file and use the appropriate command, however I am not quite sure how to do this. With the current code I have, I simply get the error:
autotar.sh: line 18: conditional binary operator expected
autotar.sh: line 18: syntax error near `==*.tar.gz'
autotar.sh: line 18: `if [[ ${filename -d} ==*.tar.gz ]]'
Upvotes: 0
Views: 54
Reputation: 295669
If you want to check that a file doesn't exist:
if [[ ! -e $filename ]]; then ## works in bash or other ksh derivatives only
...or, for compatibility with older shells:
if [ ! -e "$filename" ]; then ## works in any POSIX shell
If you want to check for an extension:
if [[ $filename = *.tar.gz ]]; then ## works in bash or other ksh derivatives only
...or, to check for one of many extensions, consider a case
statement instead:
# this works in any POSIX shell
[ -e "$filename" ] || { echo "$filename does not exist" >&2; exit 1; }
# this, too, works in any POSIX shell
case $filename in
*.tar.gz|*.tgz) tar -xzf "$filename" ;;
*.tar.bz2|*.tbz2) tar -xjf "$filename" ;;
*.tar.xz|*.txz) xz -d <"$filename" | tar -xv ;;
*.zip) unzip "$filename" ;;
esac
Note, in particular:
[ "$foo" = 1 ]
is a valid and correct statement, whereas [$foo=1]
and [ "$foo" =1]
are syntax errors, and [ "$foo"==1 ]
always returns true, no matter what value foo
has.Excepting specific exemptions, quoting expansions is mandatory for correct behavior. If you're not sure, the safe thing is to use them: You can leave out quotes in [[ ]]
or case
only these have special syntax rules that make them optional. If you were using [ ]
instead, then you would need to use them: if [ ! -e "$filename" ]
.
However, tar -xzf "$filename"
or echo "$filename"
or ls "$pathname"
all need spaces to work correctly with interesting files or path (try names with spaces in testing your software; names with glob characters are another frequent cause of potential bugs, especially when combined).
[
is just a synonym for test
; it's a command, not special syntax, and commands follow normal parsing rules. Just as you can't run test$foo=false
, you can't run [$foo=false]
or [-a $filename]
; it needs to be [ -e "$filename" ]
(unary use of -a
is not present in the POSIX specification for test
, hence the switch to -e
).Upvotes: 1