linux压缩并通过bash / shell脚本排除目录

我正在尝试编写一个bash / shell脚本来压缩特定的文件夹,并忽略该文件夹中的某些子目录。

这是我试图压缩“ sync_test5 ”的文件夹:

在这里输入图像说明

我的bash脚本生成一个忽略列表( 基于 ),并像这样调用zip函数:

#!/bin/bash SYNC_WEB_ROOT_BASE_DIR="/home/www-data/public_html" SYNC_WEB_ROOT_BACKUP_DIR="sync_test5" SYNC_WEB_ROOT_IGNORE_DIR="dir_to_ignore dir2_to_ignore" ignorelist="" if [ "$SYNC_WEB_ROOT_IGNORE_DIR" != "" ]; then for ignoredir in $SYNC_WEB_ROOT_IGNORE_DIR do ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/**\*" done fi FILE="$SYNC_BACKUP_DIR/$DATETIMENOW.website.zip" cd $SYNC_WEB_ROOT_BASE_DIR; zip -r $FILE $SYNC_WEB_ROOT_BACKUP_DIR -x $ignorelist >/dev/null echo "Done" 

现在这个脚本运行没有错误,但是它不会忽略/排除我指定的目录。

所以,我有shell脚本输出它试图运行的命令,这是:

 zip -r 12-08-2014_072810.website.zip sync_test5 -x sync_test5/dir_to_ignore/**\* sync_test5/dir2_to_ignore/**\* 

现在,如果我像这样在腻子中直接运行上面的命令,它就可以工作:

在这里输入图像说明

那么,为什么我的shell脚本不能按预期工作呢? 正在执行的命令是相同的(直接在shell和putty中)。

由于分词后的变量中的反斜杠引号不计算。

如果你有a='123\4'echo $a会给

 123\4 

但是,如果你直接像echo 123\4那样做,你会得到的

 1234 

显然,你通过变量传递的参数和不带变量的参数是不同的。

你可能只是想不引用你的反斜杠:

 ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/***" 

顺便说一下,什么样的实际作品是一个非评估的glob模式:

 zip -r 12-08-2014_072810.website.zip sync_test5 -x 'sync_test5/dir_to_ignore/***' 'sync_test5/dir2_to_ignore/***' 

你可以验证这一点

 echo zip -r 12-08-2014_072810.website.zip sync_test5 -x sync_test5/dir_to_ignore/**\* sync_test5/dir2_to_ignore/**\* 

这是我的建议:

 #!/bin/bash SYNC_WEB_ROOT_BASE_DIR="/home/www-data/public_html" SYNC_WEB_ROOT_BACKUP_DIR="sync_test5" SYNC_WEB_ROOT_IGNORE_DIR=("dir_to_ignore" "dir2_to_ignore") IGNORE_LIST=() if [[ -n $SYNC_WEB_ROOT_IGNORE_DIR ]]; then for IGNORE_DIR in "${SYNC_WEB_ROOT_IGNORE_DIR[@]}"; do IGNORE_LIST+=("$SYNC_WEB_ROOT_BACKUP_DIR/$IGNORE_DIR/***") ## "$SYNC_WEB_ROOT_BACKUP_DIR/$IGNORE_DIR/*" perhaps is enough? done fi FILE="$SYNC_BACKUP_DIR/$DATETIMENOW.website.zip" ## Where is $SYNC_BACKUP_DIR set? cd "$SYNC_WEB_ROOT_BASE_DIR"; zip -r "$FILE" "$SYNC_WEB_ROOT_BACKUP_DIR" -x "${IGNORE_LIST[@]}" >/dev/null echo "Done" 

经过一些试验和错误,我已经设法通过改变这一行来解决这个问题:

 ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/**\*" 

至:

 ignorelist="$ignorelist $SYNC_WEB_ROOT_BACKUP_DIR/$ignoredir/***" 

不知道为什么这个工作,但它确实:)

这是我结束了:

 #!/bin/bash # This script zips a directory, excluding specified files, types and subdirectories. # while zipping the directory it excludes hidden directories and certain file types [[ "`/usr/bin/tty`" == "not a tty" ]] && . ~/.bash_profile DIRECTORY=$(cd `dirname $0` && pwd) if [[ -z $1 ]]; then echo "Usage: managed_directory_compressor /your-directory/ zip-file-name" else DIRECTORY_TO_COMPRESS=${1%/} ZIPPED_FILE="$2.zip" COMPRESS_IGNORE_FILE=("\.git" "*.zip" "*.csv" "*.json" "gulpfile.js" "*.rb" "*.bak" "*.swp" "*.back" "*.merge" "*.txt" "*.sh" "bower_components" "node_modules") COMPRESS_IGNORE_DIR=("bower_components" "node_modules") IGNORE_LIST=("*/\.*" "\.* "\/\.*"") if [[ -n $COMPRESS_IGNORE_FILE ]]; then for IGNORE_FILES in "${COMPRESS_IGNORE_FILE[@]}"; do IGNORE_LIST+=("$DIRECTORY_TO_COMPRESS/$IGNORE_FILES/*") done for IGNORE_DIR in "${COMPRESS_IGNORE_DIR[@]}"; do IGNORE_LIST+=("$DIRECTORY_TO_COMPRESS/$IGNORE_DIR/") done fi zip -r "$ZIPPED_FILE" "$DIRECTORY_TO_COMPRESS" -x "${IGNORE_LIST[@]}" # >/dev/null # echo zip -r "$ZIPPED_FILE" "$DIRECTORY_TO_COMPRESS" -x "${IGNORE_LIST[@]}" # >/dev/null echo $DIRECTORY_TO_COMPRESS "compressed as" $ZIPPED_FILE. fi