Linux Bash - 排除带有find的目录

时间:2016-03-04 17:00:51

标签: linux bash sh

我正在编写一个当前正在编写的bash脚本时出现问题,并且我已经隔离了有问题的代码。

使用变量中的参数时查找命令不会排除目录。

现在我需要分配' -not -path ./dir'变量的参数,因为它被循环,但如果我这样做,它似乎不起作用。

我已经包含了产生所需输出的命令下方,以及我当前打破的版本。请参阅下面的测试:

变量赋值

findIgnorePaths="-not -path ./\.git\* -not -path ./administrator/cache\* -not -path ./images\* -not -path ./logs\* -not -path ./cache\* -not -path ./media\* -not -path ./plugins\* -not -path ./tmp\*"

期望的输出。

find ./ -type d -not -path ./\.git\* -not -path ./administrator/cache\* -not -path ./images\* -not -path ./logs\* -not -path ./cache\* -not -path ./media\* -not -path ./plugins\* -not -path ./tmp\*

输出损坏

find ./ -type d ${findIgnorePaths}

对于任何想要查看我的脚本的人,我正在解决上述问题,请查看以下内容:

原始剧本(不需要阅读以回答问题,但......为那些好奇的灵魂提供)

#!/bin/sh

declare -a ignoreDirs=()
findIgnorePaths=""
seperator="\e[33m**********************************\e[0m\n"

clear
printf "\n\n"

if [[ "${PWD##*/}" != "public_html" ]]
then
    printf "\e[31mThis script will not run unless current location is; /home/*/public_html/*\e[0m\n"
    exit
fi

echo "Site Locker! This will change all directory permissions to 555. And all file permissions to 444. Read only accces."

echo #Move to new line
echo "Are you sure you want to make changes to files/directories within the below location?"
printf "$seperator"
printf "\e[0;49;96m${PWD##/home/}\e[0m\n"
printf "$seperator"
echo #Move to new line

read -r -p "Y/n " response
echo #Move to new line
if [[ $response =~ ^([nN][oO]|[nN])$ ]]
then
    printf "\n\e[31mNo changes made. Quitting.\e[0m\n\n"
    exit
fi

printf "\e[95mIf you're working with a Joomla site, please select\nthe **JOOMLA** preset in the list below.\e[0m\n\nPlease select directory #) to add to the ignore list:\n\e[92m"

currentDir=( "**SAVE/SKIP**" "**JOOMLA**" )
currentDir+=( $(find . -maxdepth 1 -type d) )
select DIR in ${currentDir[@]};
do
  case $DIR in
        *SAVE*)
          printf "\n\n\e[92mDone!!\e[0m\n\n"
          break
          ;;
        *JOOMLA*)
          printf "\n\e[92mApplying Joomla preset.\n"
          ignoreDirs+=("./.git" "./administrator/cache" "./cache" "./images" "./logs" "./media" "./tmp" "./plugins")
          findIgnorePaths+=" -not -path ./\.git\* -not -path ./administrator/cache\* -not -path ./images\* -not -path ./logs\* -not -path ./cache\* -not -path ./media\* -not -path ./plugins\* -not -path ./tmp\*"
          printf "\n\n\e[31mIgnore list:\n"
          for item in "${ignoreDirs[@]}"
          do
              printf "$item\n"
          done
          ;;
        *)
          ignoreDirs+=("$DIR")
          findIgnorePaths+=" -not -path ${DIR}\*"
          printf "\n\n\e[31mIgnore list:\n"
          for item in "${ignoreDirs[@]}"
          do
              printf "$item\n"
          done
          printf "\e[92m"
          ;;
  esac
done
findIgnorePaths=$(echo ${findIgnorePaths} | cut -c 1-)

printf "\e[0m\n"

echo #Move to new line
printf "$seperator"
echo #Move to new line

echo "Apply 555 permissions to the below directories & all sub directories? "
printf "$seperator"
printf "\e[0;49;96m"

echo
echo "$findIgnorePaths"
echo
find ./ -maxdepth 1 -type d -not -path ./\.git\* -not -path ./administrator/cache\* -not -path ./images\* -not -path ./logs\* -not -path ./cache\* -not -path ./media\* -not -path ./plugins\* -not -path ./tmp\*
echo
find ./ -maxdepth 1 -type d ${findIgnorePaths}
echo



printf "\e[0m\n"
printf "$seperator"

read -r -p "Y/n " response
echo #Move to new line
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
then
    find ./ -type d $findIgnorePaths -exec chmod 555 {} +
    printf "\e[92mChanged directory permissions to 555\e[0m\n\n"
else
    printf "\e[31mSkipping this step. No directory permissions were set.\e[0m\n\n"
fi

read -r -p "Apply 444 permissions to all files in; ${PWD##*/}? Y/n " response
echo #Move to new line
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
then
    find ./ -type f $findIgnorePaths -exec chmod 444 {} +
    printf "\e[92mChanged file permissions to 444\e[0m\n\n"
else
    printf "\e[31mSkipping this step. No file permissions were set.\e[0m\n\n"
fi

printf "\n\e[92mFinished!\e[0m\n\n"

1 个答案:

答案 0 :(得分:2)

这是Bash FAQ 50,建议您使用array variable将参数传递给程序:

findIgnorePaths=(-not -path './.git*' -not -path './administrator/cache*' -not -path './images*' -not -path './logs*' -not -path './cache*' -not -path './media*' -not -path './plugins*' -not -path './tmp*')
find ./ -type d "${findIgnorePaths[@]}"

注意目录globs是单引号,因此在创建变量时shell不会解释它们。你的反斜杠逃脱做了同样的事情;这是个人偏好的问题,你觉得哪一个更容易阅读。

通过shellcheck.net运行脚本总是一个好主意,可以找到潜在的任何问题。

另外,/bin/sh不是/bin/bash,所以修复你的shebang!