我正在尝试编写一个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