1

I'm trying to do a simple script that unzips a zip file which has an exclamation mark in its name:

#!/bin/bash
UNZIP='/usr/bin/unzip'
CUT="/usr/bin/cut"
GREP="/usr/bin/grep"
FILENAME="test"

FILE="/usr/local/var/www/htdocs/"$FILENAME"\!3.zip"
UNZIPPEDFOLDER=$($UNZIP ${FILE} | $GREP -m1 'creating:' | $CUT -d' ' -f5-)
echo $UNZIPPEDFOLDER

but when script is being executed, unzip returns:

unzip:  cannot find or open /usr/local/var/www/htdocs/test\!3.zip, /usr/local/var/www/htdocs/test\!3.zip.zip or /usr/local/var/www/htdocs/test\!3.zip.ZIP.

It works fine when there is no "!" sign in filename, but to make some of my work automated, I need to stay with original file names.

1

In general you don't have to escape and quote anything. The secure way to write this would be:

FILE="/usr/local/var/www/htdocs/${FILENAME}!3.zip"
UNZIPPEDFOLDER="$("$UNZIP" "$FILE" | "$GREP" -m1 'creating:' | "$CUT" -d' ' -f5-)"
echo "$UNZIPPEDFOLDER"
2

! is the command history expansion character so needs to be quoted on the command-line when history expansion is enabled. It does not need to be quoted inside a script.

From the man page:

When the command history expansion facilities are being used (see HISTORY EXPANSION below), the history expansion character, usually !, must be quoted to prevent history expansion.

and

Non-interactive shells do not perform history expansion by default.

see man bash, search for QUOTING and HISTORY EXPANSION for full details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.