2016-03-04 17 views
3

我遇到了一些麻烦,我正在写一个bash脚本,我已经隔离了有问题的代码。Linux 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" 

回答

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[@]}" 

注意目录水珠是单引号,这样可以创建变量时,他们不会被shell解释。你的反斜杠转义正在做同样的事情;这是个人喜好的问题,你可以更容易阅读。

通过shellcheck.net运行脚本始终是一个好主意,可以发现潜在的任何问题。

另外,/bin/sh不是/bin/bash,所以修理你的屁股!

+0

啊谢谢你!非常丰富和有用的答案,这帮助我解决了我的问题。 –