Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash tar error doesn't create tar.gz

Tags:

linux

bash

tar

I have the following bash script:

#DIR is something like: /home/foo/foobar/test/ without any whitespace but can also include whitespace
DIR="$( cd "$( dirname "$0" )" && pwd )"
#backup_name is read from a file
backup_name=FOOBAR
date=`date +%Y%m%d_%H%M_%S`
#subdirs is also read from the same file
subdirs=etc/ sbin/ bin/
filename="$DIR/Backup_$backup_name"_"$date.tar.gz"

cd /
echo "filename: $filename"
echo "subdirs $subdirs"
cmd='tar czvf "'$filename'" '$subdirs
echo "cmd tar: $cmd"
$cmd

But I get following output:

filename: /home/foo/foobar/test/Backup_FOOBAR_20120322_1529_35.tar.gz
subdirs: etc/ sbin/ bin/
cmd tar: tar cfvz "/home/foo/foobar/test/Backup_FOOBAR_20120322_1529_35.tar.gz" etc/ sbin/ bin/
etc/
# ... list of files in etc
# but no files from sbin or bin directory
tar: "/home/foo/foobar/test/Backup_FOOBAR_20120322_1529_35.tar.gz": can open not execute: File or directory not found
tar: not recoverable error: abortion.

However, when I copy the echo output of the tar command, make a cd to / and paste it into the bash shell it is working:

tar cfvz "/home/foo/foobar/test/Backup_FOOBAR_20120322_1529_35.tar.gz" etc/ sbin/ bin/
etc/
  • Every variable is defined and there is no trailing newline
  • I also tried $cmd with backticks
  • the two variables: backup_name and subdirs are read from a file (I did not include the reading process in the code)

edit: I just copied my script to a dir with no whitespace and changed the line:

cmd='tar czvf "'$filename'" '$subdirs
#to
cmd="tar czvf $filename $subdirs"

and it's working now but when I do the same in a dir which also contents whitespaces I get still the same error.

edit2: reading from file (the file is read before anything else happens)

config="config.txt"
local line
while read line
do
    #points to next free element and declares it
    config_lines[${#config_lines[@]}]=$line
done <$config
backup_name=${config_line[0]}
subdirs=${config_line[1]}

What is wrong with my bash script?

like image 621
creativeDev Avatar asked Dec 12 '25 01:12

creativeDev


1 Answers

Short answer: see BashFAQ #050: I'm trying to put a command in a variable, but the complex cases always fail!.

Long answer: embedding quotes in a variable doesn't do anything useful, because when you use it (i.e. $cmd), bash parses quotes before replacing variables; by the time the quotes are there, it's too late for them to do any good. You do, however, have several options:

  1. Don't bother with putting the command in a variable in the first place, just use it directly:

    echo "filename: $filename"
    echo "subdirs $subdirs"
    tar czvf "$filename" $subdirs
    
  2. If you really need to put it in a variable first, use an array rather than a plain text variable (and ideally, do the same with the subdirs list):

    subdirs=(etc/ sbin/ bin/)
    ...
    
    echo "filename: $filename"
    echo "subdirs ${subdirs[*]}"
    cmd=(tar czvf "$filename" "${subdirs[@]}")
    printf "cmd tar:"
    printf " %q" "${cmd[@]}" # Have to do some trickery to get it printed right
    printf "\n"
    "${cmd[@]}"
    
like image 198
Gordon Davisson Avatar answered Dec 14 '25 16:12

Gordon Davisson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!