【问题标题】:delete folder contents except a specified folder and its contents删除指定文件夹及其内容以外的文件夹内容
【发布时间】:2014-04-01 15:15:55
【问题描述】:

根据我的另一个问题,我有一个脚本可以快速轻松地更新 drupal 核心。

目前,它将站点文件夹移出目录,删除站点文件夹的内容,然后将站点文件夹移回。

mv ./sites ../sites
rm -rf *
cp -R /sources/drupal-7/* ./
mv ../sites ./sites

考虑到站点文件夹可能会变得相当大,我想尽可能避免移动它,只删除其他文件夹,只留下站点文件夹。

我在互联网上尝试了一些其他建议,其中一些来自这里,其中一个使用了 find,但也删除了站点文件夹内的文件和文件夹。

我还想保持源文件夹不变,即:在其中保留一个站点文件夹以供新站点使用,并且仅将其他文件/文件夹复制到站点以进行更新,例如:

rm -rf * !sites/*
cp -R /sources/drupal-7/* ./ !sites/*

我尝试了很多方法,其中大多数根本不起作用或出现语法错误(或删除网站或其内容)

编辑:为清楚起见,这是整个脚本:

#/bin/bash
CWD=$(pwd)
cd $CWD
echo $CWD
if [[ $CWD = "/var/www/vhosts/"* ]]; then
    echo "Updating drupal core files"
    read -r -p "do you need to keep the .htaccess file? [y/N]" response

if [ $response = y ] 
then
    /usr/local/bin/drush vset maintenance_mode 1
    mv ./.htaccess ../.htaccess
    mv ./sites ../sites
    rm -rf *
    cp -R /sources/drupal-7/* ./
    cp -R /sources/drupal-7/.* ./
    mv ../sites ./sites
    mv ../.htaccess ./.htaccess
    chown -R httpd:httpd *
    /usr/local/bin/drush up && /usr/local/bin/drush updb
    /usr/local/bin/drush cc all && /usr/local/bin/drush cron
    /usr/local/bin/drush vset maintenance_mode 0

elif [ $response = n ] 
then
    /usr/local/bin/drush vset maintenance_mode 1
    mv ./sites ../sites
    rm -rf *
    cp -R /sources/drupal-7/* ./
    cp -R /sources/drupal-7/.* ./
    mv ../sites ./sites
    chown -R httpd:httpd *
    /usr/local/bin/drush up && /usr/local/bin/drush updb
    /usr/local/bin/drush cc all && /usr/local/bin/drush cron
    /usr/local/bin/drush vset maintenance_mode 0
else
    echo "Response must be either y or n"
fi

else
        echo "not in a web directory, exiting"
fi

【问题讨论】:

  • 如果... 是不同的文件系统,则mv ./sites ../sites 必须复制所有文件并删除原始文件。但是,如果它们在同一个系统上,它只是一个简单的重命名。利用这一事实,您可以做一些更像mkdir tmp; mv * tmp; mv tmp/sites .; rm -rf tmp...虽然下面的bash extglob 想法也不错...
  • ./ 和 ../ 是同一个驱动器,但不同的文件夹。我还没有在大型站点文件夹上测试过工作脚本,还没有看到它需要多长时间。基于此,我可能是在浪费我的时间哈哈

标签: linux bash cp mv rm


【解决方案1】:

根据 cmets 中的建议进行了更新:

find /path/to/dir -maxdepth 1 -mindepth 1 ! -name "sites" -type d -print0 | xargs -0 rm -rf

【讨论】:

  • 您可以先尝试使用 find 命令来验证您是否获得了正确的目录列表,然后使用 xargs 删除它们
  • +1: 虽然我会使用xargs-I 选项来处理带有空格的目录。
  • 抱歉,-0 并使用 print0find
  • 我应该补充说,在这种情况下,当前目录是在@kevin:[[ $CWD = /var/www/vhosts/"* ]] 的帮助下建立的受限模式之一,以使脚本在多个虚拟主机中工作。将/path/to/dir 替换为$CWD 后,它删除了整个站点文件夹(幸运的是它没有移动到vhosts 文件夹中),并删除了站点文件夹中的所有内容。
  • rm -rf 总是有风险的,正如我在评论中提到的,最好在将它们传递到 xargs 之前检查 find 只返回所需的目录。
【解决方案2】:

在 bash 中,您可以启用扩展 glob (shopt -s extglob),然后使用 !(sites)

bash-3.2$ shopt -s extglob
bash-3.2$ rm -r !(sites)

bash-3.2$ cp -R /sources/drupal-7/!(sites) .

【讨论】:

  • 我之前曾尝试使用 shopt -s extglob,但收到:-bash: !: event not found.
  • 再次运行shopt -s extglob 以确保
  • 如果是在脚本里,你需要把它放在脚本里,因为它不会继承它。
  • 我在脚本中添加了shopt -s extglobrm -r !(sites),我收到了这个:syntax error near unexpected token ('`
  • 您使用的是什么系统和 bash 版本?
猜你喜欢
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多