Drupal Drush Command-Line Utility
Administer and maintain your Pantheon site from your local Drupal Drush installation.
Discuss in our Forum Discuss in SlackDrush is a command-line interface for Drupal that provides a wide set of utilities for administering and maintaining your site.
Drush commands require a settings.php
file, and it's a best practice to have one. Drupal 8 sites come with a bundled settings.php
file out of the box. Drupal 6 and 7 sites do not contain a settings.php
file; however, you can simply copy the sites/default/default.settings.php
to sites/default/settings.php
via SFTP or Git for Drush to work on older Drupal versions. For more details, see Configuring Settings.php.
Terminus Drush and Local Drush
Refer to Drush's install documentation for details on installing Drush locally.
Drush-savvy developers should also install and utilize Terminus, a command-line interface that allows you to control your Pantheon account and sites. Virtually anything you can do in the Dashboard, you can script with Terminus. It can also make remote Drush calls on your environments without having Drush installed locally, eliminating incompatibility issues between locally and remotely installed versions of Drush.
If you have a Composer-based site, Terminus will use the version of Drush it finds in vendor/bin/drush
when running Drush commands on the platform.
You can run all of the commands below from Terminus instead of using Drush aliases. For more information, see Managing Drupal Sites with Terminus and Drush. For example, you can run terminus drush <site>.<env> -- cc drush
instead of drush @pantheon.SITENAME.dev cc drush
.
Drush Versions
For details on managing remote and local Drush versions, see Managing Drush Versions on Pantheon.
Download Drush Aliases Locally
Downloading the Pantheon aliases to your local Drush aliases file allows you to run Drush calls against your Pantheon site environments. Use Terminus to download your Drush aliases.
Authenticate Terminus with machine tokens or your Pantheon Dashboard credentials, then update your local aliases file in a single step:
terminus aliases
This command will write both Drush 8 and Drush 9 aliases into the directory $HOME/.drush
for your sites that you are a direct member of. To create aliases for all sites that you can use, including sites that you have access to via team membership, run:
terminus aliases --all
If you add a site to your account, you will have to download a new copy of your Drush aliases. You do not need to update your Drush aliases when you add new Mulitdev environments to your sites.
Note
You must use Drush 8.3.0 or 9.6.0 or later to use Drush aliases directly. Earlier versions are not compatible.
Structure of Site Aliases
The form Pantheon Drush aliases take depends on the version of Drush being used. Drush 8 aliases are all written to a single file, $HOME/.drush/pantheon.aliases.drushrc.php
. A single alias record looks something like the example below:
$aliases['example.*'] = array(
'uri' => '${env-name}-example.pantheonsite.io',
'remote-host' => 'appserver.${env-name}.3eb7b5dd-8b90-4272-8a80-5474015c37f1.drush.in',
'remote-user' => '${env-name}.3eb7b5dd-8b90-4272-8a80-5474015c37f1',
'ssh-options' => '-p 2222 -o "AddressFamily inet"',
'path-aliases' => array(
'%files' => 'files',
),
);
Drush 9 aliases are written one file per site to the directory $HOME/.drush/sites/pantheon
. The site name is used to generate the filename, e.g. example.site.yml
. The contents of a Drush 9 alias file looks something like the following example:
'*':
host: appserver.${env-name}.3eb7b5dd-8b90-4272-8a80-5474015c37f1.drush.in
paths:
files: files
uri: ${env-name}-example.pantheonsite.io
user: ${env-name}.3eb7b5dd-8b90-4272-8a80-5474015c37f1
ssh:
options: '-p 2222 -o "AddressFamily inet"'
tty: false
Note
You must be a site team member of the site for it to be included within your local alias file. Organization administrators will not see all associated sites within their alias file, but only sites for which they are site team members. The alternative is to execute Drush commands via Terminus for sites in which you are not a direct site team member.
Note that these are both "wildcard" aliases. The same wildcard alias is used for every environment available for a given site. The variable ${env-name}
is replaced with the appropriate environment name when used.
Pantheon also uses "policy files" to validate aliases before they are used. The policy files are written by the terminus aliases
command; the Drush 8 policy file is written to $HOME/.drush/pantheon/drush8/pantheon_policy.drush.inc
, and the Drush 9 policy file is written to $HOME/.drush/pantheon/Commands/PantheonAliasPolicyCommands.php
. These files should not be deleted.
List Available Site Aliases
Once the Pantheon Drush aliases have been copied, verify that the site aliases are available by listing every site alias known to Drush:
drush sa
Execute a Drush Command on a Pantheon Site Environment
Once you see the target site in the list of site aliases, you can execute a command on any remote site listed. The syntax is:
drush @pantheon.SITENAME.ENV COMMAND
Warning
Do not use Drush to update Drupal core on Pantheon. Pantheon uses Pressflow and includes some additional functionality; Drush assumes that a site is using vanilla Drupal and erroneously overwrites Pressflow. For more details, see Core Updates.
Registry Rebuild
Note
Registry Rebuild is deprecated for Drupal 8 and will only work on Drupal 7.
Drupal's list of PHP classes and files can get corrupted or out-of-date, typically when moving code. If clearing the cache doesn't resolve the issue due to a required class during bootstrap, the registry may need to be rebuilt. To facilitate this, Pantheon has installed registry_rebuild
as an available Drush command on every site, which can be executed via Terminus.
Do not attempt to install the module on your site. This command is provided as-is, without warranty, so make a backup first.
terminus drush <site>.<env> -- rr
Note that the Registry Rebuild command is only ever necessary on Drupal 7 and Drupal 6 sites. The command drush cache:rebuild
for Drupal 8 serves the same function that registry rebuild
does for older versions of Drupal.
Run SQL Queries Using Drush on Pantheon
The drush sql-cli
and drush sql-connect
commands are not supported on Pantheon. For security reasons, the SQL database is not directly accessible from your local machine.
You can, however, use Terminus as follows:
echo 'SELECT * FROM users WHERE uid=1;' | terminus drush SITENAME.ENV sql:cli
Note that certain characters such as ;
cannot be used in the query. If you use an illegal character, you will get an error message "Command not supported as typed."
Note that the trailing ;
in the SQL query is optional in this context.
Execute PHP Code Using Drush on Pantheon
The drush php-eval
command is not supported on Pantheon. You can run PHP commands after bootstrapping Drupal on Pantheon via the following workaround:
echo 'print "hello world";' | drush @pantheon.SITENAME.ENV php-script -
Also, the interactive PHP shell works as well:
terminus drush <site>.<env> -- core-cli
Filter Drush Responses
Use the --filter
command to extract relevant information from terminus drush
responses.
For example, to get the line containing information about your installed version of PHP from the Drupal status report page:
terminus drush mysite.env -- core:requirements --filter='title=php'
+-------+----------+--------------------------------------------------+
| Title | Severity | Summary |
+-------+----------+--------------------------------------------------+
| PHP | Info | 7.3.14 (<a href="/admin/reports/status/php">more |
| | | information</a>) |
+-------+----------+--------------------------------------------------+
To extract just the Summary
field without any of the table formatting, add --field=Summary
to the end of the command, and the result would be a simple string:
terminus drush <site>.<env> -- core-cli
7.3.14 (<a href="/admin/reports/status/php">more information</a>)
Drush Commands That Alter Site Code
Commands that alter site code, such as pm-download (dl), will only work on a Dev environment that has been set to SFTP mode from the Pantheon Dashboard.
Add Custom Drush Commands
While we have the full spectrum of Drush core already available for your use, you may want to add a command that you regularly use; for instance, Drush Search and Replace (sar).
Put the site in Git mode.
Clone locally.
Create a
drush
folder in the Drupal root.Add the
sar
Drush command to the Drush folder.Commit
drush/sar
.Push your code up to Pantheon.
Clear your Drush cache on each environment. Example:
drush @pantheon.SITENAME.dev cc drush
For Drupal 9, place Drush commands in drush/Commands
.
Drush Alias Strict Control
Create a file called policy.drush.inc
, and place in in the .drush
folder of your home directory. You can create a new file or use the example policy file in Drush’s examples
folder to get started.
If your live site is associated with multiple domains, Pantheon will select an arbitrary one to include in the alias file that you download with Terminus. In some instances, it can cause problems in Drupal if the wrong URI is used, and Drush will not allow you to override the URI value in the alias with a command line --uri
option.
To avoid editing the generated Pantheon aliases file every time it is downloaded, use a hook_drush_sitealias_alter
function in policy.drush.inc
to change the URI for your specific Pantheon site:
function policy_drush_sitealias_alter(&$alias_record) {
// Provide the correct 'uri' for a specific site
if ($alias_record['#name'] == 'pantheon.SITENAME.live') {
$alias_record['uri'] = 'example.com';
}:title=settings.php
}
Replace SITENAME
with your Pantheon site name, and example.com
with the correct URI for that site.
Troubleshooting
Reading the Pantheon Environment from Drush
Since Drush does not run via the web server, reliance on the $_SERVER
superglobal is problematic as some of the contents of that array will be missing, ['PANTHEON_ENVIRONMENT']
in particular. Drush commands and policy files should instead reference $_ENV
when reading Pantheon environment information. For more information, please see our documentation on using the $_SERVER
superglobal in custom code.
Terminus Drush Silent Failure
The following silent failure occurs when executing terminus drush
commands on environments that use redirect logic without checking to see if Drupal is running via the command line:
[notice] Command: <site>.<env> -- 'drush <command>' [Exit: 1]
[error]
Redirects kill the PHP process before Drush execution is complete. You can resolve this error by adding php_sapi_name() != "cli"
as a conditional statement to all redirect logic within settings.php
:
// Require HTTPS, www.
if (isset($_ENV['PANTHEON_ENVIRONMENT']) &&
($_ENV['PANTHEON_ENVIRONMENT'] === 'live') &&
// Check if Drupal or WordPress is running via command line
(php_sapi_name() != "cli")) {
if ($_SERVER['HTTP_HOST'] != 'www.yoursite.com' ||
!isset($_SERVER['HTTP_USER_AGENT_HTTPS']) ||
$_SERVER['HTTP_USER_AGENT_HTTPS'] != 'ON' ) {
header('HTTP/1.0 301 Moved Permanently');
header('Location: https://www.yoursite.com'. $_SERVER['REQUEST_URI']);
exit();
}
}
Drush Commands on Remote Aliases Not Working from Inside Local Drupal Install
Some Drush 5 commands need to be executed from outside the context of a local Drupal installation, due to a known issue with Drush 5. The output from a Drush 5 command run in this context looks like the following:
drush @pantheon.SITENAME.ENV status
PHP configuration : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/php53.in
i
/srv/bindings/754cbef0a7b54a07ab07167ef8de7377/php53.in
i
Drush version : 5.10.1
Drush : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/drushrc.
configuration php
To make your Drush 5 commands work on Pantheon aliases, change your directory to a context outside of a working local Drupal installation:
pwd
/Users/USERNAME/Sites/SITENAME
cd ..
pwd
/Users/USERNAME/Sites/
drush @pantheon.SITENAME.ENV status
Drupal version : 7.26
Site URI : ENV-SITENAME.pantheonsite.io
Database driver : mysql
Database hostname : 10.178.14.16
Database username : pantheon
Database name : pantheon
Database : Connected
Drupal bootstrap : Successful
Drupal user : Anonymous
Default theme : bartik
Administration theme : seven
PHP configuration : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/php5
3.ini
/srv/bindings/754cbef0a7b54a07ab07167ef8de7377/php5
3.ini
Drush version : 5.10.1
Drush configuration : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/drus
hrc.php
Drupal root : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/code
Site path : sites/default
File directory path : sites/default/files
Private file : sites/default/files/private
directory path
Temporary file : /srv/bindings/754cbef0a7b54a07ab07167ef8de7377/tmp
directory path
Drush Error: "Unknown option: --db-url"
drush @pantheon.SITENAME.ENV cc all
Unknown option: --db-url. See `drush help cache-clear` for available [error]
options. To suppress this error, add the option --strict=0.
To resolve this error, follow the suggestion and add the option --strict=0
:
drush @pantheon.SITENAME.ENV cc all --strict=0
'all' cache was cleared in [success]
/srv/bindings/BINDINGID/code#ENV-SITENAME.pantheonsite.io
This only affects Drupal 7 sites running a Drush version below Drush 8
Drush Error: "No Drupal site found", "Could not find a Drupal settings.php file", or missing system information from status
Could not find a Drupal settings.php file at ./sites/default/settings.php
To resolve, add a default or empty sites/default/settings.php
to your site's code.
Unable to Connect to MySQL Server
Sometimes, you may encounter the following error when running Drush MySQL commands:
ERROR 2003 (HY000): Can't connect to MySQL server on 'dbserver.dev.SITE_ID.drush.in' (61)
This can happen when an inactive site has spun down. To resolve this error, wake environments by loading the home page or with the following Terminus command:
terminus env:wake SITENAME.ENV
Unable to Connect to drush.in Hostnames (DNS)
Some ISPs have issues resolving a drush.in hostname; if you're having trouble connecting to a drush.in hostname, you can use the dig
command to investigate further.
dig appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.8.1-P1 <<>> appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 38905
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in. IN A
;; Query time: 11 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Aug 30 12:28:25 2012
;; MSG SIZE rcvd: 78
As you can see in the output above, the status REFUSED suggests improper resolution. The next step is to run dig
with a specified DNS server. We recommend using Google's DNS (8.8.8.8):
dig @8.8.8.8 appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.8.1-P1 <<>> @8.8.8.8 appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36494
;; flags: qr rd ra; QUERY: 1, ANSWER: 34, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in. IN A
;; ANSWER SECTION:
appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in. 599 IN A 67.207.144.213
...
appserver.live.38f2bd91-0000-46cb-9278-0000000000000.drush.in. 599 IN A 67.207.143.122
;; Query time: 52 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Aug 30 13:02:00 2012
;; MSG SIZE rcvd: 622
In this example, Google's DNS is able to properly resolve the drush.in hostname.
You can adjust your local settings to use Google's DNS (8.8.8.8 and 8.8.4.4) instead of the default provided by your ISP to properly resolve the hostnames.
Timeouts When Using Long-Running Migrate or Other Drush Commands
Long-running Drush commands that produce no output will cause the SSH gateway to timeout. Pantheon's timeouts for SSH based commands are outlined in our documentation on timeouts. To avoid a timeout related to a lack of output, be sure your commands return output to the terminal session in under 10 minutes.
For example, using the --feedback
flag:
drush migrate-import migration --feedback="1000 lines processed"
Drush error: Failed opening required .../vendor/bin/includes/preflight.inc
Fatal error: require(): Failed opening required '/srv/bindings/.../code/vendor/bin/includes/preflight.inc' (include_path='.:/usr/share/pear:/usr/share/php') in /srv/bindings/.../vendor/bin/drush.php on line 11
This indicates that the vendor directory contains Drush binaries that should be removed. Remove any Drush files from vendor/bin
and vendor/drush
using git rm
.
Known Limitations
Crontab: Currently, there is no way to manage Crontab on Pantheon. If you need a way to set up your own Cron interval, you can use an external cron service such as Easy Cron.
The following Drush commands are not supported and will not work on Pantheon sites:
sql-sync-pipe
. Usesql-sync
instead.sql-cli
(sqlc
) andsql-query
(sqlq
) See: Run SQL Queries Using Drush on Pantheonphp-eval
(eval
,ev
) See: Execute PHP Code Using Drush on Pantheon
Due to our highly available architecture, Drush
sql-sync
cannot currently be executed on the live environment with more than 1 application container. We recommend you use terminus orsql-sync
a multidev, dev or test environment which only has 1 application container.Drush may fail if the
['uri']
array key has a different domain than what is expected by Drupal, resulting in the following error:drush @pantheon.example.live st Drush command terminated abnormally due to an unrecoverable error. [error]
To resolve this error, conditionally set
$uri
based on the environment indrushrc.php
, such as:if (isset($_ENV['PANTHEON_ENVIRONMENT']) && ($_ENV['PANTHEON_ENVIRONMENT'] === 'live')) { $uri = 'https://www.example.com'; } $options['uri'] = $uri;
The most reliable locations to put
drushrc.php
files are:__ROOT__/drush/drushrc.php __ROOT__/../drush/drushrc.php __ROOT__/sites/default/drushrc.php
Changelog
Drush Changelog
10.3.6
- Document support of Symfony Console commands. Fix #4545.
- Fix #4544. Use exit code 3 when insecure packages are found in security commands
- Allow Symfony Finder ^5 (#4571)
- Improve command categorization. (#4572)
- Fixes #4580: Allow Drush to work with composer/semver ^3. (#4581)
- entity:delete -> execute deletion of entities in batches. Add progress bar.
- Fixed app root detected by Drush not getting passed to the Drupal kernel
10.3.5
- Interact support for cc bin @weitzman (#4540)
- Fixed lease-time option on queue:run @tuutti (#4550)
- Fix PHP 8 deprecation with required parameters (#4557)
- Transform the storage to import instead of the active one for export @bircher (#4554)
- Allow to work with guzzle 7 also (#4562)
10.3.4
- Document and update xhprofCommands. Support both xhprof and tideways (#4534)
- Fix #4536. Move unish docs (#4537)
- Avoid exception when clearing Drush’s own cache files (#4535)
10.3.3
- Fix the backup-dir configuration setting (#4510)
- Error message from requirements check on updatedb (#4513)
- Fix #4512. Drush::redispatchOptions() no longer includes shortcut options (-y) (#4515)
- Issue #4032 queue run lease time (#4322)
- Fix #4134,#4438. Use Guzzle to fetch json in security commands (#4522)
- Change how we NULL the cache dir during deploy command. (#4533)
- Lots of minor docs improvements. See our new site at www.drush.org, including a command list.
8.3.6
- Allow Drush 8 uli to call Drush 10 and get the right reset link. (#4498)
- Do not pass --root in sql-sync if it is not set in the alias file. (#4484)
- Wrap mysql table names in backticks to avoid errors in MySQL 8 (#4456)
- Adjust Drush8 alias files search depth (#4436)
- Remove entity_load function in favour of Role::load to be Drupal 9 compatible (#4431)
10.3.1
- Handle semver contrib releases in pm:security (#4449)
- Success log message when checking php security updates (#4446)
10.3.0
Highlights
- Add new pm:security-php command for checking PHP dependencies for vulnerabilities (#4346)
- Add new deploy command. Performs site deployment. (#4359)
Other changes
- Add release and EOL dates to Drush versions table (#4349)
- Do not throw an exception when valid JSON data evaluates to empty PHP data (#4342)
- Simpler dcf template (#4354)
- Fix SQL user creation with MariaDB (#4364)
- Output correct data for machine readable formats when active and imported config are identical. (#4340)
- Add deploy:hook command for hook_deploy_NAME "update hooks" (#4365)
- Don't use the UpdateKernel for config:import. (#4368)
- Add cache clear to early part of deploy. (#4375)
- Fix #4371. Reunite ConfigImportCommands classes. They no longer need the UpdateKernel (#4374)
- Log Drupal messages during site:install by registering a logger service in Drupal container (#4378)
- Document how to rerun watchdog:show every 2 seconds. (#4381)
- Add command to export .po files (#3253)
- Declare the minimum supported version of Robo (#4441)
8.3.3
Bugfix release primarily fixing issues to support:
10.2.2
- Escape command name in RedispatchToSiteLocal. (#4307)
- Allow for showing DB creds when running SQL commands (#4316)
- Fix #4317. Fix Windows error when trying to drush uli into a remote site using an alias.
- Fix #4319. missing application/gzip mime type (#4320)
- Fix locale import usage example (#4321)
- Add another DrushTT example from Scheduler module. ba37f21
- Refactor alwaysQuery for Oracle. (#4335)
- Drupal 9.0 compat - ConfigImport (#4336)
9.7.2
- 4dea224b - Remove unhelpful help text after drush terminated abnormally.
- 661db961 - Fix #3867. Improve rsync confirmation message. (10 weeks ago
- b6350cad - Remove old example from sql:sync help.
- b0a2a2e4 - Closes #4071 by setting -y to sql-sync command
- ae6c3b4d - Add --items-limit option to queue:run command (#4121)
- 8848863b - Expand examples for drush ssh command. (4 months ago)
- cad7fcf1 - Calculate memory_limit correctly when there is no suffix
- 9ced786c - Issue-4208: Fix User:login command incorrect url handling
- 61f78fde - fix warning in site:install
- 08316911 - Replace classy with stark in EnDisUnListInfoCase::testEnDisUnList
- 87b6e789 - Use CAPS for env variables in examples.
- b59f72e2 - Do not throw exception if cron is already running (#4162)
- 90e5acf7 - Fix #4160. Make method non-static.
- ef24b8e2 - Allow symfony/event-dispatcher 4.x.
- 1f5b487a - Fixes . Escape rsync params.
- ab23651f - Remove usage of prepareLegacyRequest().
- 471d9ae7 - Remove unused method on test class.
- 359fa136 - Add documentation on wildcard aliases (#4113)
10.2.1
- Use Drupal's new core-recommended template in Unish. (#4304)
- Add missing base theme key (affects Drupal 9). (#4309)
10.2.0
- Drush site-install fails with MySQL 8 #4259
- Adding extra information about symlinked packaged commands, see #4290
- Tolerate an unrecognized DB Driver during site:install and bootstrap #4295
- Change from an exception to warning in site:install f93ee99
- Better error message when dropping tables. 4906f6c
- Remove unused SqlBase::delete f5dc954
- Bump Unish's Drupal 9 testing to PHP 7.3 f10313c
- Stop using CONFIG_SYNC_DIRECTORY. (#4301)
- Fix #4098. In Drush config, stop using sql.db-su in favor of just db-su. (#4302).
- Fix #4275. Adjust install instructions for recommended-project.
10.1.1
- Add Usage example to sql:query linking to #3071.
- Remove unhelpful help text after drush terminated abnormally.
- Change log level to debug for 'broaden constraint' warning.
- Bring back drush_log() to avoid fatal errors from older commandfiles.
10.1.0
- Add
cache:tags
command to purge content by tag. (#4267) - Allow symfony/var-dumper version 5. 637f2aa
- Fix #4256. Insufficient Error messages on failing SQL commands during site:install
- Use entity_field.manager in user field sanitize plugin. Drupal 9 compat. #4270
- More Drupal 9 compat #4272 #4273
- Use PHP 7.3.7 exclusively at Appveyor. #4271
- Fix userTest on Windows. 493467f
- Improve rsync confirm message aa47e57a
10.0.0
Drush 10 removes many deprecated APIs and functions. It's lean and clean. Drush 10 works great with improvements in the upcoming Drupal 8.8, like the new Config Transform and Exclude APIs.
Commandfiles written for Drush 9 are often already compatible with Drush 10. All you should do is expand the constraint in your module's composer.json (see extra/drush
section). See this patch from Devel module. Commandfiles that aren't part of modules don't need any composer.json changes.
Drush 10 should work fine when making remote calls into a Drush 9.6+ environment. This helps during the brief period when you upgrade to Drush 10 locally but still need to make calls into a Prod instance that is still on Drush 9.