It is required that Drupal sites be built using Composer, with Drush listed as a dependency. Popular starter templates for that include drupal-project (Drush is included) and recommended-project (Drush must be added). If your Composer project doesn't yet depend on Drush, run composer require drush/drush to add it. Finally, we run the command to clear the Drupal caches. Drush cc all; The installation process is complete. Now, the user can use the Drush command easily. Troubleshooting common Drush on Drupal 8 installation errors. From our experience in managing servers, we often see errors reported by customers while installing Drush in Drupal 8. Drush uinf $(drush sqlq 'SELECT GROUPCONCAT(uid) FROM users LIMIT 99999') PS: Currently I do not have a Drupal-installation at hand, so I can now test for myself, sorry:-(– El Hannes Dec 4 '20 at 12:16. Drush is a shell-based application used to control, manipulate, and administer Drupal sites. On the surface, drush is an excellent tool for updating site modules, but here is a more comprehensive list of features for drush: Quick status report (get Drupal site version). Use Drush to install Drupal Now that is everything in place you have to install Drupal. One way is the install script, which will start if you visit your site URL like myproject.local.
Pick a version
Each version of Drush supports multiple Drupal versions. Drush 7 is current stable Drush.
|Drush Version||Drush Branch||PHP||Compatible Drupal versions||Code Status|
|Drush 9||master||5.5+||D7, D8|
|Drush 8||8.x||5.4.5+||D6, D7, D8|
|Drush 7||7.x||5.3.0+||D6, D7|
|Drush 6||6.x||5.3.0+||D6, D7||Unsupported|
|Drush 5||5.x||5.2.0+||D6, D7||Unsupported|
|Drush 4||4.x||5.2.0+||D5, D6, D7||Unsupported|
|Drush 3||3.x||5.2.0+||D5, D6||Unsupported|
Pick an install method
The four sections below describe ways to install Drush. None is superior to the others.
Composer - One Drush for all Projects
- Optional - video instructions by Drupalize.me.
- Install Composer globally.
To install Drush 7.x (stable):
To install Drush 8.x (dev) which is required for Drupal 8:
Now add Drush to your system path by placing
export PATH='$HOME/.composer/vendor/bin:$PATH'into your ~/.bash_profile (Mac OS users) or into your ~/.bashrc (Linux users).
To update to a newer version (what you get depends on your specification in ~/.composer/composer.json):
Alternate commands to install some other variant of Drush:
To install for all users on the server:
- If Drush cannot find an autoloaded class, run
composer self-update. Drush often tracks composer changes closely, so you may have some problems if you are not running a recent version.
- If composer cannot find a requirement, and suggests that The package is not available in a stable-enough version according to your minimum-stability setting, then place the following in
Merge this in with any other content that may already exist in this file.
See Configure for next steps.
Composer - One Drush per Project
- If your web site is built from a composer.json file (see https://github.com/drupal-composer/drupal-project), add the following to the
composer installfor a new project or
composer updatefor an existing one. Do so from the same directory as composer.json.
- Optional: Copy the /examples/drush file to your project root and modify to taste. This is a handy launcher script.
- To update, change the drush/drush line and run
Git Clone (i.e. manual install)
- Place the uncompressed drush.tar.gz, drush.zip, or cloned git repository in a directory that is outside of your web root.
Make the 'drush' command executable:
$ chmod u+x /path/to/drush/drush
Configure your system to recognize where Drush resides. There are 3 options:
Create a symbolic link to the Drush executable in a directory that is already in your PATH, e.g.:
$ ln -s /path/to/drush/drush /usr/bin/drush
Explicitly add the Drush executable to the PATH variable which is defined in the the shell configuration file called .profile, .bash_profile, .bash_aliases, or .bashrc that is located in your home folder, i.e.:
Add an alias for drush (this method can also be handy if you want to use 2 versions of Drush, for example Drush 5 or 6 (stable) for Drupal 7 development, and Drush 7 (master) for Drupal 8 development). To add an alias to your Drush 7 executable, add this to you shell configuration file (see list in previous option):
$ alias drush-master=/path/to/drush/drush
For options 2 and 3 above, in order to apply your changes to your current session, either log out and then log back in again, or re-load your bash configuration file, i.e.:
$ source .bashrc
Test that Drush is found by your system:
$ which drush
From Drush root, run Composer to fetch dependencies.
$ composer install
Drupal Drush Clear Cache
See Configure for next steps.
Windows Zip Package
Windows support has improved, but is still lagging. For full functionality, consider running Linux/Unix/OSX via Virtualbox, or other virtual machine platform. The Vlad virtual machine is popular.
These Windows packages include Drush and its dependencies (including MSys).
- 7.0.0 (stable).
Unzip the downloaded file to anywhere thats convenient on your system.
Whenever the documentation or the help text refers to
drush [option] <command> or something similar, 'drush' may need to be replaced by 'drush.bat'.
Most Drush commands will run in a Windows CMD shell or PowerShell, but the Git Bash shell provided by the Git for Windows installation is the preferred shell in which to run Drush commands.
When creating site aliases for Windows remote machines, pay particular attention to information presented in the example.aliases.drushrc.php file, especially when setting values for 'remote-host' and 'os', as these are very important when running Drush rsync and Drush sql-sync commands.
Batch processing is usually an important aspect of any Drupal project and even more when we need to process huge amounts of data.
The main advantage of using batch is that it allows large amounts of data to be processed into small chunks or page requests that run without any manual intervention. Rather than use a single page load to process lots of data, the batch API allows the data to be processed as number of small page requests.
Using batch processing, we divide a large process into small pieces, each one of them executed as a separate page request, thereby avoiding stress on the server. This means that we can easily process 10,000 items without using up all of the server resources in a single page load.
This helps to ensure that the processing is not interrupted due to PHP timeouts, while users are still able to receive feedback on the progress of the ongoing operations.
Some uses of the batch API in Drupal:
- Import or migrate data from an external source
- Clean-up internal data
- Run an action on several nodes
- Communicate with an external API
Normally, batch jobs are launched by a form. However, what can we do if we want a *nix crontab to launch them on a regular basis? One of the best solutions is to use an external command like a custom Drush command and launch it from this crontab.
In this post we are going to create a custom Drush 9 command that loads all the nodes of a content type passed in as an argument (page, article ...). Then a batch process will simulate a long operation on each node. Next, we'll see how to run this drush command from crontab.
You can find the code for this module here: https://github.com/KarimBoudjema/Drupal8-ex-batch-with-drush9-command
This is the tree of the module:
We are going to proceed in three steps:
- Create a class to host our two main callback methods for batch processing (BatchService.php).
- Create our custom Drush 9 command to retrieve nodes, to create and process the batch sets (ExBatchDrush9Commands.php).
- Create a crontab task to run automatically the Drush command at scheduled times.
1. Create a BatchService class for the batch operations
A batch process is made of two main callbacks functions, one for processing each batch and the other for post-processing operations.
So in our class will have two methods,
processMyNode() for processing each batch and
processMyNodeFinished() to be launched when the batch processing is finished.
It's best practice to store the callback functions in their own file. This keeps them separate from anything else that your module might be doing. In this case I prefer to store them in a class that we can reuse later as a service.
Here is the code of BatchService.php
processMyNode()method we are going to process each element of our batch. As you can see, in this method we just simulate a long operation with the
usleep() PHP function. Here we could load each node or connect with an external API. We also grab some information for post-processing.
processMyNodeFinished() method, we display relevant information to the user and we can even save the unprocessed operations for a later process.
2. Create the custom Drush 9 command to launch the batch
This is the most important part of our module. With this Drush command, we'll retrieve the data and fire the batch processing on those data.
Drush commands are now based on classes and the Annotated Command format. This will change the fundamental structure of custom Drush commands. This is great because we can now inject services in our command class and take advantage of all the OO power of Drupal 8.
A Drush command is composed of three files:
Drupal Drush Migrate
drush.services.yml - This is the file where our Drush command definition goes into. This is a Symfony service definition. Do not use your module's regular services.yml as you may have done in Drush 8 or else you will confuse the legacy Drush, which will lead to a PHP error.
You'll can see that in our example we inject two core services in our command class:
entity_type.manager to access the nodes to process and
logger.factory to log some pre-process and post-process information.
composer.json - This is where we declare the location of the Drush command file for each version of Drush by adding the extra.drush.services section to the composer.json file of the implementing module. This is now optional, but will be required for Drush 10.
MyModuleCommands.php - (src/Commands/ExBatchDrush9Commands.php in our case) It's in this class that we are going to define the custom Drush commands of our module. This class uses the Annotated method for commands, which means that each command is now a separate function with annotations that define its name, alias, arguments, etc. This class can also be used to define hooks with @hook annotation.
Some of the annotations available for use are:
@command: This annotation is used to define the Drush command. Make sure that you follow Symfony’s module:command structure for all your commands.
@aliases: An alias for your command.
@param: Defines the input parameters. For example, @param: integer $number
@option: Defines the options available for the commands. This should be an associative array where the name of the option is the key and the value could be - false, true, string, InputOption::VALUE_REQUIRED, InputOption::VALUE_OPTIONAL or an empty array.
@default: Defines the default value for options.
@usage: Demonstrates how the command should be used. For example, @usage: mymodule:command --option
@hook: Defines a hook to be fired. The default format is @hook type target, where type determines when the hook is called and target determines where the hook is called.
For a complete list of all the hooks available and their usage, refer to: https://github.com/consolidation/annotated-command
Here is the code for our Drush command.
In this class, we first inject our two core services in the
Next, in the updateNode() annotated method we define our command with three annotations:
@param string $type - Defines the input parameter, the content type in our case.
@command update:node - Defines the name of the Drush command. In this case it's 'update:node' so we would launch the command with:
@aliases update-node - Defines an alias for the command
The main part of this command is the creation of the operations array for our batch processing (See points 3,4,5 and 6). Nothing strange here, we just define our operations array (3 and 4) pointing to the two callback functions that are located in our BatchService.php class.
Once the batch operations are added as new batch sets (5), we process the batch sets with the function
drush_backend_batch_process(). This is a drop in replacement for the existing
batch_process() function of Drupal. It will process a Drupal batch by spawning multiple Drush processes.
Finally, we show information to the user and log some information for a later use.
That's it! We can now test our brand new Drush 9 custom command!
To do so, just clear the cache with
drush cr and launch the command with
3. Bonus: Run the Drush command from crontab
As noted before, we want to run this custom command from crontab to perform the update automatically at the scheduled times.
The steps taken may vary based on your server's operating system. With Mac, Linux and Unix servers, we manage scheduled tasks by creating and editing crontabs that execute cron jobs at specified intervals.
1. Open a terminal window on your computer and enter the following command to edit your crontab - this will invoke your default editor (usually a flavor of vi):
2. Enter the following scheduled task with our Drush command (where [docroot_path] is your server's docroot):
We need to add an environment path in our cron table first line (cron commands run one after anonther).
This command will run our custom Drush command every five minutes.
3. Restart the cron service with the following command:
4. Check if the command is running
We can check the log of our Drupal application every five minutes since we logged some information with the command itself, but we can also use another way with the following command:
- We created a class to host our two main callback methods for batch processing (BatchService.php).
- We created a custom Drush 9 command to retrieve nodes, to create and process the batch sets, injecting core services, like entity_type.manager to access the nodes to process and logger.factory to log some pre-process and post-process information.
- We created a crontab task to run automatically the Drush command at scheduled times.
This way, we can now run heavy processes, on a regular basis without putting undue stress on the server.
Porting Commands to Drush 9 (Moshe Weitzman's Blog)
Creating Drush 9 commands and porting legacy commands (Gbyte)
Processing expensive back-end operations (Lullabot)
Batch Processing In Drupal 8 (Access)
function batch_set (Drupal API)
function callback_batch_operation (Drupal API)
Drupal Drush Command
View the discussion thread.