3

I have created a shell script to complete 3 simple tasks (zip a directory, rename the final file and delete the source directory). The script source is below:

#!/bin/bash
if [[ $2 == *"/data/"* ]]
then
    src= $2"/*";
    dest= $1".zip";

    # Just for test
    echo $src;

    # Commented for now
    #zip -r -j $dest $src
    #mv $dest $1
    #rm -rf $2
else
    echo "Invalid arguments";
fi

When I run the script above with these parameters I have with error:

./scriptzip.sh /data/file-new /data/file-old

./scriptzip.sh: line 4: /data/file-old/*: No such file or directory
./scriptzip.sh: line 5: /data/file-new.zip: No such file or directory

How can prevent the shell to test a variable for "directory like" string? There is any way to skip that?

h2odev
  • 133
  • 1
  • 1
  • 3

1 Answers1

8

The space is significant in the shell, as that's what divides the tokens in commands such as echo foo bar or worse rm -rf /some/where /. Hence, assignment must not include spaces around the =:

foo=/etc/*
echo $foo

Variables may also need quoting, depending on exactly what you want to happen for here glob expansion and also word splitting (incorrect word splitting to rm can result in unexpected (and hilarious) filesystem cleanups).

echo "$foo"
thrig
  • 1,626
  • 9
  • 9
  • On quoting: it's best to leave the wildcards out of variables, and then double-quote variable references. E.g. `src="$2"; dest="$1.zip"; zip -r -j "$dest" "$src"/*`. Also, you really really should check for any errors (especially on the `zip` command), and if there are any *do not delete the source files*. – Gordon Davisson Aug 21 '16 at 04:16
  • Thank You Gordon, I agree with you. In fact this script (now in production) has changed a lot from this example (even to avoid any stupidity from "rm -rf" ). Also you have right about the source file deletion but in this case I needed an "atomic operation". And of course, the script itself will called carefully by PHP with "well checked" inputs. I had to use a shell script to make these background tasks ( **exec( "nohup " . $cmd . " > /dev/null 2>&1 & echo $!", $out );** ) and get the PID of this process to use later (To check the status: exec( "ps -p " . $pid, $out ); ). Thank You again. – h2odev Aug 21 '16 at 14:10