Drupal Command Line Scripts with Drush

Drupal's scripting abilities just keep getting better and better. Since publishing my Drupal Command Line Script Template last year I've moved exclusively to the Drush php-script (scr) command. The script template article still gets a lot of page views - perhaps because with all the functionality in Drush it's easy to miss the scripting feature - so posting an update seems like a good idea.

Drush Scripting Advantages/Disadvantages

The advantages of using Drush over using my original template are:

  • Drush takes care of creating the Drupal environment for the script to run in, which is the only function the template served. Using Drush factors out the environment common code, eliminating redundant code in individual scripts.
  • Drush makes it easy to place the script files in a directory outside of the Drupal website home directory. Placing script files outside the website home directory eliminates a whole range of security issues.
  • The Drush code that creates the Drupal environment is reviewed by the community, making it far more robust than something a single person could create or maintain on their own.
  • When the code required to create the Drupal environment changes you don't need to update individual templates, just Drush.

The only disadvantage with Drush (I've found) is its kludginess in the MS Windows environment. At the time I was using Drush on Windows there were path idiosyncrasies with the -l and -r parameters. I've since moved to a Macintosh and am not familiar with the current situation.

Installing Drush

There are Drush installation instructions in the Drush README.txt file, and tutorials posted on the project page: http://drupal.org/project/drush. If the instructions or a particular tutorial don't make sense try another, there are a number to choose from. Laura Scott's tutorial, Installing Drush on Mac OS X, resonated with me (in great part because there are text instructions as well as the video).

Running Scripts from Drush

Once you've got Drush installed, running a Drupal script is as simple as:

$ drush scr ~/drupal/scripts/demo.php

or

$ drush php-script ~/drupal/scripts/demo.php

As I mentioned in the introduction, it's so straight forward it's easy to miss.

There's also a handy php evaluate option, php-eval, for executing a single line of code.

$ drush php-eval "print print_r(node_load(1), 1)"

The above examples assume you've changed the command line current directory to your Drupal site's base directory. If you use the -r parameter to specify the Drupal base directory, you can run the script from anywhere in your directory tree.

Additional Notes

  • If your Drupal setup.php file is not in sites/default you'll need to use the -l option. For example, if my Drupal site was configured as http://testsite.local, and the setup.php files was in sites/testsite.local, then my command would look like:
    $ drush -l testsite.local scr demo.php
  • Before I do any Drush work I like issuing the following command to make sure everything is running the way I think it's running:
    $ drush status
  • Using the -r parameter Drush can target a specific Drupal site regardless of your current directory. In other words, you don't have to change (cd) your current directory to the Drupal site's base directory. When I'm doing scripting work I'll typically run drush from the directory where the scripts live, not from the Drupal site directory. For example, if the Drupal site directory is /var/www/testsite, the Drush command is:
    $ drush -r /var/www/testsite status
    $ drush -r /var/www/testsite scr demo.php
  • The Drush alias feature can simplify the preceding point. Lullabot has feature write-up here: New features in Drush 3

Unless you have a specific use case that precludes Drush, it's the only way to go for Drupal scripting!

Comments

This sounds awesome. What is a use case for command line scripting? Do you use this often?

I mostly use it for development tasks like code fragment testing, especially when exploring how an API works, and data import/export. I've also used it for "one of" site changes, like bulk changing URLs/creating aliases to the old URLs. For updates, I feel much more comfortable doing a node load/modify/change than changing the database directly.

Some other things I used to from a script, like run cron, are now built into Drush.

If I put my test code into Unix file /tmp/qq, shouldn't this work?

$ drush -r /Applications/MAMP/htdocs/my_site scr /tmp/qq

Instead, I get an error message:

Unable to find any of the following: /usr/local/drush/commands/core//tmp/qq.php, [error]
/Users/john/.drush/tmp/qq.php
An error occurred at function : drush_core_php_script [error]

How about Unix stdin for scripts?

drush -r /Applications/MAMP/htdocs/my_site scr < <?php
> echo "php\n";
> echo "test\n";
> ?>
> EOF

The result is a weird message:

/usr/local/drush/commands/core/scratch.php

And what about this common paradigm?

$ cat - < <?php echo "test\n"; ?>
> EOF
Unable to find any of the following: /usr/local/drush/commands/core/-.php, [error]
/Users/john/.drush/tmp2/-.php
An error occurred at function : drush_core_php_script [error]

For reference, this works:

$ cat - < <?php echo "test\n"; ?>
> EOF
test

John, I've also encountered some problems running scripts from other directories but don't recall which situations. And MS Windows had was weird with some parameter combinations. Using the script directory as the current directory and specifying the Drupal root is how I typically work and I haven't had problems. The information you've posted here might have more impact if you feed it back to the Drush project as an issue or GDO comment (http://groups.drupal.org/drush)

Thanks, I will do so. To be clear, this is a 100% Unix use case - assuming MacOSX can be considered 100% Unix! :-)

Anyway, I typically work in a common Unix manner which seems a bit different than the "Drupal way" mentioned on the 'Net, and I'm sure I'm not the only one. I'd like to promote acceptance and compatibility of working in a common Unix manner, hence the need for drush to work with standard Unix paradigms like STDIN.

Do you suppose there will be good acceptance of this perspective, or are experienced Drupal-er's more likely to have a "Microsoft attitude" about things, eg, re-inventing wheels with disregard for standard practices already well established in other IT areas? There's no problem supporting multiple working styles, but it shouldn't occur at the expense of not allowing standard methodologies in the first place.

If Drush was your baby, would you consider investing efforts for such compatibility even though you wouldn't make use of these yourself? Thanks for feedback...

http://groups.drupal.org/node/94304

I found a partial work-around on the new web page (http://drush.ws/help/3).

A shame I had to spend (aka "waste") a few hours on this topic. However, if the net result is a fix which saves time for others in the future, then I'm glad to help.

Thanks...