function drush_main

8.0.x drush_main()
6.x drush.php drush_main()
7.x drush.php drush_main()
3.x drush.php drush_main()
4.x drush.php drush_main()
5.x drush.php drush_main()
master drush_main()

The main Drush function.

  • Runs "early" option code, if set (see global options).
  • Parses the command line arguments, configuration files and environment.
  • Prepares and executes a Drupal bootstrap, if possible,
  • Dispatches the given command.

function_exists('drush_main') may be used by modules to detect whether they are being called from Drush. See and

Return value

mixed Whatever the given command returns.

2 calls to drush_main()
drush.php in ./drush.php
Drush is a PHP script implementing a command line shell for Drupal.
drush_run_main in includes/
Run drush_main() and then exit. Used when we cannot hand over execution to the launcher.


includes/, line 34
Preflight, postflight and shutdown code.


function drush_main() {
  // Load Drush core include files, create the container and
  // parse commandline arguments
  $container = drush_preflight_prepare();
  if ($container === FALSE) {
    return (1);
  // Start code coverage collection.
  if ($coverage_file = drush_get_option('drush-coverage', FALSE)) {
    drush_set_context('DRUSH_CODE_COVERAGE', $coverage_file);
    xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);

  // Load the global Drush configuration files, and global Drush commands.
  // Find the selected site based on --root, --uri or cwd
  // Preflight the selected site, and load any configuration and commandfiles associated with it.
  // Select and return the bootstrap class.
  $bootstrap = drush_preflight();

  // Reset our bootstrap phase to the beginning

  $return = '';
  if (!drush_get_error()) {
    if ($file = drush_get_option('early', FALSE)) {
      require_once drush_is_absolute_path($file) ? $file : DRUSH_BASE_PATH . DIRECTORY_SEPARATOR . $file;
      $function = 'drush_early_' . basename($file, '.inc');
      if (function_exists($function)) {
        if ($return = $function()) {
          // If the function returns FALSE, we continue and attempt to bootstrap
          // as normal. Otherwise, we exit early with the returned output.
          if ($return === TRUE) {
            $return = '';
    else {
      // TODO: If 'DRUSH_SYMFONY' is set, then disable the legacy command
      // runner, and use only the Symfony Application.  n.b. the legacy runner
      // will also try to run commands via the Symfony Application runner if
      // it cannot find a matching legacy Drush command.
      if (getenv('DRUSH_SYMFONY')) {
        drush_log(dt("Dispatching directly with Symfony application (DRUSH_SYMFONY set)"), LogLevel::BOOTSTRAP);

        // Get the application and run it.
        // TODO: We need a new way to handle @alias arguments,
        // remote command dispatching, bootstrapping, etc.
        $application = $container->get('application');
        $input = drush_symfony_input();
      else {
        // Do any necessary preprocessing operations on the command,
        // perhaps handling immediately.
        $command_handled = drush_preflight_command_dispatch();
        if (!$command_handled) {
          drush_log(dt("Dispatching using Drush bootstrap_and_dispatch"), LogLevel::BOOTSTRAP);
          $return = $bootstrap->bootstrap_and_dispatch();
  // TODO: Get rid of global variable access here, and just trust
  // the bootstrap object returned from drush_preflight().  This will
  // require some adjustments to Drush bootstrapping.
  // See:
  if ($bootstrap = \Drush::bootstrap()) {
  if (is_object($return)) {
    $return = 0;

  // How strict are we?  If we are very strict, turn 'ok' into 'error'
  // if there are any warnings in the log.
  if (($return == 0) && (drush_get_option('strict') > 1) && drush_log_has_errors()) {
    $return = 1;

  // After this point the drush_shutdown function will run,
  // exiting with the correct exit code.
  return $return;