2

I am creating an sh file to run multiple commands in the background.

At some line in this file, there is a command to update a zip file like:

zip -d archive.zip file.txt

This file.txt might not be a part of the archive.zip always. When it isn't, the shell script breaks in that line with:

zip warning: name not matched

I want it to continue to the following lines with ignoring non-existence of this file. How can I accomplish this?

0

1 Answer 1

4

Normally in a shell script, even a line that generates an error will not stop the shell script from executing. It will just go on to the next line.

The notable exception is if you have set the flag for it to exit the shell if any sub-command fails. This is sometimes done by adding "set -e" near the top of a script. If you have something like that in your script it will abort on any command in the script returning an error. Your options in this case are:

  • Remove that option. This might have ramifications for the rest of your script so don't do this on a whim.

  • Toggle the option off for the section of the script you are in, then turn it back on to continue:

    set +e
    zip -d archive.zip file.txt
    set -e
    
  • Provide a way-out for the failing line so that the shell sees the command as a success even if something failed. This can be done a lot of ways but one simple one is to use the OR operator:

    zip -d archive.zip file.txt || true
    

    This will run the zip command, but if it fails it will run the true command and the parent shell will get the return code from that (which is of course, a success). You might see this sometimes written ||: which is slightly faster and trickier but not magic; : just happens to be a shell builtin no-op command that will also return a success error code even though it does nothing.

    Another way to do this is to run the command in a sub-shell by surrounding it in () so that while the command inside it may fail, the subshell will have done it's job so the parent script with set -e set won't die. This is sub-optimal for a single command but can be useful if you want to run a whole set of things.

On the other hand if you just want to suppress the error message generated by zip, you can redirect the stardard error stream to /dev/null with (2> /dev/null) to suppress the generated messages (or close it with 2>&-).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .