bash スクリプトのコマンドラインから感嘆符付きのファイルを解凍する

bash スクリプトのコマンドラインから感嘆符付きのファイルを解凍する

名前に感嘆符が付いている zip ファイルを解凍する簡単なスクリプトを実行しようとしています。

#!/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

しかし、スクリプトが実行されると、unzip は次を返します:

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.

ファイル名に「!」記号がない場合でも正常に動作しますが、作業の一部を自動化するには、元のファイル名のままにする必要があります。

答え1

!はコマンド履歴拡張文字なので、履歴拡張が有効な場合はコマンドラインで引用符で囲む必要があります。スクリプト内では引用符で囲む必要はありません。

man ページから:

コマンド履歴拡張機能が使用されている場合 (以下の履歴展開を参照)、履歴展開を防ぐために、履歴展開文字 (通常は !) を引用符で囲む必要があります。

そして

非対話型シェルは、デフォルトでは履歴の展開を実行しません。

詳細については、を参照するか、 をman bash検索してください。QUOTINGHISTORY EXPANSION

答え2

一般的には逃げる必要はないそして 引用何でもいいです。これを安全に書く方法は次のとおりです。

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

関連情報