Skip to content

Drush Commands — Drupal Command Line Interface Complete Guide

DodaTech Updated 2026-06-27 9 min read

In this tutorial, you'll learn how to use Drush, the Drupal command-line shell: installing sites, managing caches, exporting and importing configuration, running database operations, managing modules, creating users, running cron, and writing custom Drush commands.

What You'll Learn

  • What Drush is and how to install it via Composer
  • Site installation with drush site:install
  • Cache management: cache:rebuild, cache:clear, and cache types
  • Configuration Management: config:export, config:import, config:get, config:set
  • Database commands: sql:dump, sql:cli, sql:query, sql:sanitize
  • Module commands: pm:install, pm:uninstall, pm:list, pm:enable
  • User commands: user:create, user:login, user:block, user:password
  • Cron commands: cron, core:cron
  • State commands: state:get, state:set

Why It Matters

Drush transforms how you work with Drupal. Instead of clicking through the admin interface for every task, you run a single command. Deploying a site becomes drush cim && drush cr instead of a dozen clicks. Database dumps become drush sql:dump > backup.sql. User management becomes drush user:create. For site builders, developers, and system administrators, Drush is the most efficient way to manage Drupal sites.

Real-World Use

A Drupal developer manages 50 sites across multiple environments. Without Drush, every deployment requires: logging into the admin UI, navigating to configuration import, clicking through warnings, rebuilding cache, and running cron. With Drush, a deployment script runs: git pull, composer install, drush updb, drush cim, drush cr. The entire Process takes 30 seconds. When a user reports a login issue, the developer runs drush user:login admin to get a one-time login link without touching the database directly.

Learning Path

flowchart LR
  A[Drupal API] --> B[Drush Commands]
  B --> C[Installation and Setup]
  C --> D[Cache Commands]
  D --> E[Config Management]
  E --> F[Database Operations]
  F --> G[Module and User Commands]
  G --> H[Custom Drush Commands]

What is Drush?

Drush (Drupal Shell) is a command-line tool written in PHP that provides hundreds of commands for managing Drupal. It communicates with Drupal directly, bypassing the web server, making it faster and more reliable than web-based operations.

Key capabilities:

  • Install, configure, and maintain Drupal sites
  • Run updates and database migrations
  • Import and export configuration
  • Manage users, modules, and cron
  • Create custom commands using the Drush API

Installing Drush

# Install Drush globally via Composer
composer global require drush/drush

# Or install it as a project dependency
composer require drush/drush

# Verify installation
drush --version
# Output: Drush 12.x.x

# List all available commands
drush list

# Get help for a specific command
drush help cache:rebuild

Site Installation

Start a new Drupal site from the command line:

# Install Drupal with standard profile
drush site:install \
  --db-url=mysql://user:password@localhost/drupal_db \
  --site-name="My Site" \
  --site-mail=admin@example.com \
  --account-name=admin \
  --account-pass=securepassword \
  --account-mail=admin@example.com

# Short form
drush si \
  --db-url=mysql://user:password@localhost/drupal_db \
  --site-name="My Site"

# Install with a custom install profile
drush si my_custom_profile \
  --db-url=mysql://user:password@localhost/drupal_db

# Install with existing settings.php
drush si --existing-config

# Set the default language
drush si --locale=fr

Cache Commands

Cache management is the most frequently used Drush operation:

# Rebuild all caches (most common command)
drush cache:rebuild
# Short form
drush cr

# Clear a specific cache bin
drush cache:clear render
drush cache:clear page
drush cache:clear dynamic_page_cache

# Clear all caches (older Drupal versions)
drush cache:clear all

# Check cache status
drush cache:get cache_container

When to run cache:rebuild:

  • After enabling or disabling modules
  • After changing configuration
  • After updating Twig templates
  • After adding libraries (CSS/JS)
  • When changes do not appear on the front end

Configuration Management

Drush makes configuration export and import fast and reliable:

# Export all configuration to the sync directory
drush config:export
# Short form
drush cex

# Export to a specific directory
drush cex --destination=/path/to/config

# Import all configuration from the sync directory
drush config:import
# Short form
drush cim

# Import a single config item
drush config:import --filter=system.site

# View a specific configuration value
drush config:get system.site name
# Output: system.site:name [My Site]

# Set a configuration value
drush config:set system.site name "New Site Name"

# List all configuration
drush config:list

# Delete a configuration item
drush config:delete system.site name

# Show differences between active and sync config
drush config:diff

# Export a single configuration item
drush config:export --filter=node.type.article

Database Commands

Database operations without leaving the terminal:

# Export a database dump
drush sql:dump > backup.sql

# Export with options
drush sql:dump \
  --result-file=/backups/drupal.sql \
  --structure-tables-key=common \
  --extra=--skip-lock-tables

# Import a database dump
drush sql:cli < backup.sql

# Open an interactive SQL shell
drush sql:cli

# Run a raw SQL query
drush sql:query "SELECT nid, title FROM node_field_data WHERE status = 1"

# Show database connection details
drush sql:connect

# Sanitize the database (for dev copies)
drush sql:sanitize

# Show database size
drush core:status

Database sanitization replaces sensitive data:

# Sanitize removes or anonymizes:
# - User passwords
# - Email addresses
# - Usernames
drush sql:sanitize

# Custom sanitization options
# --sanitize-email: Replace emails with safe values
# --sanitize-password: Replace all passwords
drush sql:sanitize \
  --sanitize-email=user+%uid@example.com \
  --sanitize-password=changeme

Module Commands

Manage modules efficiently:

# List all modules
drush pm:list

# List only enabled modules
drush pm:list --status=enabled

# List only contributed modules
drush pm:list --type=module --no-core

# Enable a module
drush pm:enable pathauto views_ui
# Short form
drush en pathauto

# Disable a module
drush pm:disable pathauto

# Uninstall a module
drush pm:uninstall pathauto

# Install a module with dependencies
drush pm:enable my_module --include-dependencies

# Show module information
drush pm:info pathauto

User Commands

Create and manage users from the command line:

# Create a new user
drush user:create \
  --name=johndoe \
  --mail=john@example.com \
  --password=securepass123

# Create a user with roles
drush user:create \
  --name=editor1 \
  --mail=editor@example.com \
  --password=editorpass \
  --roles=content_editor

# Get a one-time login link (for admin access without password)
drush user:login admin
# Output: https://example.com/reset/1/1700000000/abc123def/login

# Get login link for a specific user
drush user:login --uid=5
drush user:login --name=johndoe

# Block a user
drush user:block --name=spammer

# Unblock a user
drush user:unblock --name=johndoe

# Change a user's password
drush user:password admin --password=newsecurepass

# Cancel a user account
drush user:cancel --name=johndoe

# List all users
drush user:list

# List users with specific role
drush user:list --roles=content_editor

Cron Commands

Run scheduled tasks:

# Run all cron tasks
drush cron
# Short form
drush core:cron

# Run a specific cron handler
drush cron --env=production

# Check when cron last ran
drush state:get system.cron_last

State Commands

View and set Drupal state values:

# Get a state value
drush state:get system.cron_last

# Set a state value
drush state:set system.maintenance_mode 1

# Delete a state value
drush state:delete my_module.temp_data

Custom Drush Commands

Create custom Drush commands in your module:

<?php
namespace Drupal\my_module\Commands;

use Drush\Commands\DrushCommands;

class MyCustomCommands extends DrushCommands {

  /**
   * Import content from an external API.
   *
   * @command my_module:import
   * @param string $source The API endpoint to import from.
   * @option limit Maximum number of items to import.
   * @usage my_module:import https://api.example.com/data --limit=50
   *   Import up to 50 items from the API.
   */
  public function import($source, $options = ['limit' => 100]) {
    $this->output()->writeln('Starting import from: ' . $source);
    $this->output()->writeln('Limit: ' . $options['limit']);

    try {
      // Your import logic here
      $count = \Drupal::service('my_module.importer')
        ->import($source, $options['limit']);

      $this->output()->writeln(
        sprintf('Successfully imported %d items.', $count)
      );

      $this->logger()->notice('Import completed from @source', [
        '@source' => $source,
      ]);
    } catch (\Exception $e) {
      $this->logger()->error('Import failed: @message', [
        '@message' => $e->getMessage(),
      ]);
      throw $e;
    }
  }

  /**
   * Generate a report of content statistics.
   *
   * @command my_module:report
   * @option type Content type to filter by.
   * @usage my_module:report --type=article
   *   Generate report for articles.
   */
  public function report($options = ['type' => NULL]) {
    $query = \Drupal::entityQuery('node')
      ->accessCheck(FALSE);

    if ($options['type']) {
      $query->condition('type', $options['type']);
    }

    $total = $query->count()->execute();
    $published = (clone $query)
      ->condition('status', 1)
      ->count()
      ->execute();

    $this->output()->writeln('=== Content Report ===');
    $this->output()->writeln('Total nodes: ' . $total);
    $this->output()->writeln('Published: ' . $published);
    $this->output()->writeln('Unpublished: ' . ($total - $published));
    $this->output()->writeln('=====================');
  }
}

Register the command file in my_module.services.yml:

# my_module.services.yml
services:
  my_module.commands:
    class: Drupal\my_module\Commands\MyCustomCommands
    tags:
      - { name: drush.command }

Common Mistakes

  1. Running cache:rebuild too often: Cache rebuild is expensive. Do not run it after every small change. Use targeted cache clears (render, page, Twig) when possible. Rebuild only when necessary.

  2. Using sql:dump without --result-file: Without the flag, the dump prints to stdout. Either redirect drush sql:dump > backup.sql or use --result-file to save directly to a file.

  3. Forgetting to run updatedb after code updates: After updating core or modules with Composer, run drush updatedb to apply database changes. Skipping this step causes errors.

  4. Importing config without checking differences first: Always run drush config:diff before importing. Importing unexpected configuration changes can break your site.

  5. Running sql:sanitize on production databases: Sanitization modifies user data permanently. Never run it on production. Use it only on development or staging copies.

Practice Questions

  1. Write the complete Drush command sequence to deploy a Drupal site after pulling new code from Git.
  2. How do you create a user with the "content_editor" role and a specific password using Drush?
  3. What is the difference between drush sql:dump and drush sql:cli, and when would you use each?
  4. Challenge: Write a custom Drush command that exports all published nodes of type "article" as a CSV file. The command should accept a --limit option and output the file path when complete. Include error handling for the case when no articles are found.

FAQ

What does drush cr do?

drush cr (cache:rebuild) clears all caches and rebuilds the cache tables. It is the most commonly used Drush command. Run it after enabling modules, changing configuration, updating templates, or when changes do not appear on the front end.

Can Drush work without a running Drupal site?

Yes, for many commands. Commands like drush site:install, drush sql:dump, and drush config:export work with the codebase even if the site is in maintenance mode or has errors. Other commands require a bootstrapped Drupal site.

How do I get a one-time login link for an admin?

Run drush user:login admin. Drush returns a one-time URL that logs the user in without a password. This is useful for recovering admin access if you lose the password.

What is the difference between drush cex and drush cim?

drush cex (config:export) exports active configuration from the database to YAML files. drush cim (config:import) imports YAML files into the database. Export before committing config to Git; import after deploying to a new environment.

How do I install Drush for a specific project?

Add it as a project dependency: composer require drush/drush. This installs Drush in the vendor/ directory. Run it as vendor/bin/drush or add a Composer script: composer drush -- cr.

Mini Project

Goal: Create a Drush-based deployment workflow for a Drupal site.

  1. Install Drush as a project dependency
  2. Create a bash deployment script deploy.sh that:
    • Puts the site in maintenance mode
    • Pulls the latest code from Git
    • Runs composer install --no-dev
    • Runs drush updatedb
    • Runs drush config:import
    • Runs drush cache:rebuild
    • Takes the site out of maintenance mode
  3. Create a custom Drush command called site:health that checks:
    • Whether the site is in maintenance mode
    • When cron last ran (and warns if more than 1 hour ago)
    • Number of error log entries in the last 24 hours
    • Whether trusted host patterns are configured
  4. Test the deployment script on a staging environment
  5. Write a Drush alias file for managing multiple environments (dev, staging, production)

What's Next

Now that you master Drush, proceed to configuration management to learn how to deploy configuration across environments. Then explore migrate API to learn how to migrate content from other platforms into Drupal.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro