通过Bash和Drush更新Drupal核心

昨天(译者注:对当时的作者来说是昨天),Drupal 7.28发布了。人们都想去升级,因为可能有一些长期存在的bug被修复了。人们又都犹豫要不要升级,因为升级核心不是想象中那么简单。

有时候,核心的升级是一次有关安全性的发布,这时我们需要立即跟进升级。其实,升级不需要如此痛苦的。

为Drupal7升级核心

你可能已经读过有关Drupal升级的Drupal官方文档

有两种方法,一种是下载最新的Drupal核心,然后用新的覆盖旧的核心。这样做的优点是你不会失去任何额外的文件(例如你的favicon.ico文件),但是如果你自定义了robots.txt或.htaccess时,你就会遇到麻烦,如果任何代码文件在新版本换了位置,你也会遇到问题,你的代码将同时包含新位置的文件以及旧了没有任何用处的文件。

因此,另一种办法是下载了新版本的核心之后,把所有自定义的文件以及sites目录拷贝到新版本目录。然后你删掉原来的目录,用刚刚合并好的新版本替换。问题是旧目录中有一些只读的文件和目录,比如settings.php,如果拷贝之前没有设置好,可能就会丢失文件。

所以,无论你做什么,在开始之前都应该备份,备份你的文件和数据库。

两种方式都有让人头痛的地方,时间久了,你需要创建一份关于需要copy的文件或目录的检查列表。

Drupal8承诺让这个过程更简单,但Drupal8还没有发布,(译者注:至少在翻译本文时还没有发布),甚至即使发布了,也仍然有许多站点在使用Drupal7。

为什么不用脚本么?

为什么不写一个bash脚本来为你做这个繁重的事情呢?只要你有你网站的SSH访问权限,只要你有drush的访问权限,这不是一个很困难的事情。

任何好的Drupal网站服务供应商都应该会给你shell和drush的访问权限。

因此,这里有一个bash脚本将帮你做所有这些事情。脚本将会采用上面第二种方法,在替换回当前目录之前,拷贝自定义文件到新版本目录。

注意,在开始之前一定要做备份,如果你使用了这个脚本,意味着你理解它是做什么的,并且由你对你做的事情负责

实施

在这个脚本中,有5个地方你需要输入自定义变量,告诉脚本你的Drupal安装的相关信息。其中有4个在脚本的最上方。

  • 指定Drupal的安装目录。
  • 指定一个临时目录,用来让Drush下载最新版的Drupal,这个目录不需要存在,但要有权限能被脚本来创建这个目录。
  • 指定一个文本文件,其列出了所有的你想在升级过程中要保留的文件路径,每个文件或目录一行。例如,你至少想要保留favicon.ico和logo.png。还有files目录,如果有Google Webmaster Tools用来验证所有权的文件也要留着,等等。不需要列出.htaccess文件,因为其一定会拷贝过去。
  • 指定另一个文件,我叫它~/drupal_sites.txt,包含sites目录下需要被拷贝的子站点,一行一个目录名,如果你只有一个站点,那么你只需要写进去一个default。

请注意,所有的路径配置都要用绝对路径而不是相对路径。最后:

  • 在脚本底部,是一个drush语句运行的updatedb命令,如果你的Drupal只有一个目录,那么你不需要改这里,但如果是多站点,你需要为每个站点执行updatedb。
drush -l example.com updatedb

关于Linux文件权限的一个说明

当你使用Drush下载核心的时候,其会给文件664的权限,我用的suPHP处理器需要是644权限,你如果不需要这个,可以注释掉相关的代码,或者按你需要的来设置。

实际脚本代码

这里是脚本代码,如果你喜欢的话,可以点击这个链接下载,然后重命名,给其一个sh的扩展名。

再次强调,一定要先备份。

上传到你服务器的某个地方,比如home目录,然后运行:

sh core_update.sh

里面的代码如下:

# The directory the Drupal site is installed in
DRUPAL_DIR=~/public_html

# The working directory for a temp copy of the new version
UPDATE_TMP_DIR=~/update_drupal

# A text file containing all the resources to copy across
# to the new version (favicon.ico, logo.png). One per line
# Note that .htaccess is copied anyway and should not be listed.
FILES_TO_KEEP=~/drupal_copy.txt

# A text file containing a list of all the site-specific
# subfolders within the sites directory. For most Drupal
# installations, the file should just contain one line with
# the word default. But you may list example.com,
# staging.example.com and so on, if you use multi-site
DRUPAL_SITES=~/drupal_sites.txt

# Near the bottom of the script is a Drush command to
# updatedb. You may need to add a -l switch to specify
# the sites you want to update, or use Drush aliases.
# This could be picked up from the sites txt file, but
# sometimes not all the databases referenced in
# sites/*/settings.php are accessible on this server.

# End configuration section

# 1. Clear out the temp directory from last time.
mkdir -p $UPDATE_TMP_DIR
cd $UPDATE_TMP_DIR
rm drupal* -rf

# 2. Download Drupal into temp directory,
# and get rid of version number in directory name.
drush dl drupal
mv $UPDATE_TMP_DIR/drupal* $UPDATE_TMP_DIR/drupal

# 3. Remove group-write permissions for suPHP.
chmod -R g-w $UPDATE_TMP_DIR/drupal/*

# 4. Make the sites directories writeable, so they don't get lost.
for sites in `cat $DRUPAL_SITES`; do
  chmod +w $DRUPAL_DIR/sites/$sites
  chmod +w $DRUPAL_DIR/sites/$sites/settings.php
done

# 5. Move all the files we wish to keep into the new version.
for keeps in `cat $FILES_TO_KEEP`; do
  mv $DRUPAL_DIR/$keeps $UPDATE_TMP_DIR/drupal
done
mv $DRUPAL_DIR/.htaccess $UPDATE_TMP_DIR/drupal

# 6. Copy the sites directory into the new version.
cp -r $DRUPAL_DIR/sites/* $UPDATE_TMP_DIR/drupal/sites

# 7. Scary bit: Delete everything left in the Drupal directory.
rm $DRUPAL_DIR/* $DRUPAL_DIR/.ht* -rf

# 8. Move the temp working copy into the main directory.
mv $UPDATE_TMP_DIR/drupal/* $UPDATE_TMP_DIR/drupal/.??* $DRUPAL_DIR

# 9. Run updates.
cd $DRUPAL_DIR
# drush -l example updatedb
drush updatedb

# 10. Remove temp working copy.
chmod -R +w $UPDATE_TMP_DIR/drupal
rm $UPDATE_TMP_DIR/drupal -rf

译者注:评论中说有另一个方案更简单,找时间给大家翻译一下。

作者:James
译者:理查