Here is a patch which allows Drupal to run from a shell. One example of this is to run the cron.php directly from a unix or windows cron instead of running the cron through the usual means via a request to cron.php.
This method means that the web server resources are not taken up, and the entire access to cron.php can be removed.
This also means that external processors like MTA's (eg postfix, exim) or MDA (eg procmail) can call Drupal directly to process. This means that modules like og2list do not need to use some perl code to load the mail into the drupal database, but instead call Drupal directly to process the mail as it comes in.
to execute Drupal from the shell use the following command.
php cron.php --site example.com
which will process the cron outside of the web servers process. Or
php index.php --site example.com node
which will run drupal and return the node page. This can be used to run any page.
| Comment | File | Size | Author |
|---|---|---|---|
| #63 | drupal.sh_.patch | 1.93 KB | sun |
| #57 | drupal.sh__3.txt | 3.96 KB | sun |
| #52 | drupal.sh__2.txt | 3.75 KB | sun |
| #49 | drupal.sh__1.txt | 3.73 KB | sun |
| #48 | drupal.sh__0.txt | 3.69 KB | sun |
Comments
Comment #1
killes@www.drop.org commentedNice idea!
WRT og2list, Perl was chosen for the existence of mail related libraries. We did not want to write the scripts in PHP.
Comment #2
chx commentedI wonder whether it'd be possible to replace index.php with a script (or maybe a prepend is enough?) which would preload the few necessary $_SERVER , $_REQUEST and $_GET variables from argv. This would mean that it can be a contrib for the 4.7 cycle.
Comment #3
gordon commentedKilles: Thanks, and also PHP does have these mail libraries in PEAR. I have used them before and IMHO they are quite good.
chx: This is a good idea. I don't think that it would take much to write, and could do more or less the same things.
Comment #4
chx commentedSo, you are going to write it :) ?
Comment #5
gordon commentedI have created another version which is an independant script which does the same thing as the patch but doesn't change any of the core system to run drupal from a shell.
This could actually be included in the scripts directory of 4.7 as an experimental option.
to run this you need to be in the root directory of your drupal installation and run the following
or to get the results from a page execute the following.
This will return the html of the node page to stdout.
What does also really need to be done if one of these options is included within standard, is that we should need to change watchdog() to be able to recognise the difference between the 2, and make the changes as nessecery.
Gordon.
Comment #6
killes@www.drop.org commentedVery nice, however i'd prefer if it would live in contrib cvs for the 4.7 release cycle.
Comment #7
gordon commentedI have fixed up a couple of problems with the --site option and I have added a --path option to allow you to add in the path to the command line.
Also where would be a good place to add this to contrib. It isn't really a module or a theme.
Comment #8
chx commentedcontributions/tricks is a good place imo.
Comment #9
Jaza commentedNice lil script. A
--helpoption to display a short desc on usage and available flags would be good, too.Comment #10
drummI don't think this belongs in core. contributions/tricks seems like the best place.
Comment #11
kbahey commentedGordon
Good work. I can think of many uses for it (think scripting of upgrades, extracting statistics, and many others).
You say: "the entire access to cron.php can be removed." Actually, it would be useful for the majority of sites. However, those on shared hosting that have to revert to poormanscron would not be able to use it still.
Comment #12
chx commentedWe now have an install system and this little script could live in scripts/ and make automated but somewhat customized installs possible. Just think of how dpkg-reconfigure could reuse this one.
Comment #13
moshe weitzman commentedi agree that this is a good addition to /scripts in core download
Comment #14
adrian commentedI agree completely, but i want us to be able to run install.php and update.php with it as well.
This is _especially_ useful for people hosting many sites as you could do :
for site in `ls - 1 sites`;
do
scripts/drupal.sh --cmd update.php --site $site update;
done;
Whenever they update their source.
Additionally, you could use it to do the install system, namely :
scripts/drupal.sh --cmd install.php --site mysite.com --database=mysql://username:password@localhost/dbname --profile='profilename'
Comment #15
dries commentedPlease:
1. fix the use of capital letters in user output.
2. add some PHPdoc/documentation. This needs more documentation.
Otherwise looks really interesting!
Comment #16
morbus iffSubscribing.
Comment #17
gordon commentedI have updated this script a little, with --help, and made sure it works properly.
I think we do need to do some changes to Drupal in the watchdog to record that it was run from the shell, since the host is not filled in.
FYI. I have actually been using this recently to run automated conversions from a client.
Comment #18
morbus iffI see this script as a /cli.sh not as a /scripts/drupal.sh. Much like index.php starts us off for a webserver, cli.sh starts us off for a command line interface to Drupal. Relegating this /really powerful feature/ off into a mere script directory sells it quite short - we'd be insulting it's potential for glue integration with any number of other applications.
Comment #19
gordon commenteddrupal.sh is just a name. I originally had it as a direct patch on drupal so you could just run index.php from the shell.
If you needs to be changed then it can just be renamed.
Comment #20
sunFixed some typos and grammar in usage.
Comment #21
adrian commentedIt should be fairly simple to make the script not web runnable.
I believe the argv/argc properties are only set when run via the shell. Unsure about when it is run via CGI (instead of modphp) though.
Comment #22
sunRegarding execute-protection: Why don't we create a
.htaccessin/scripts? This would prevent execution of all other shell scripts as well.Comment #23
morbus iffAccess to those scripts is already blocked in the parent/standard .htaccess of Drupal, but the concern is that some webhosts don't allow users to use .htaccess files (thus preventing the protection) and a cli.php is far more dangerous than the other scripts we ship.
Comment #24
gordon commentedWhat we could do is add a
<?
if (PHP_SAPI != 'cli') {
exit();
}
?>
which would stop it from being run in anything except a cli version of php.
This would still allow you to exec this to initiate things from the web, like the creation of a new site.
Comment #25
gordon commentedHere is an updated version with the changes the help, and other things that Dries wanted changed.
Comment #26
dries commentedIn my mind, it seems to be a lot easier to do:
./drupal.sh http://mysite.com/foo/bar
than to do:
./drupal.sh -path something -site mysite.com -foo/bar
Also, the difference between '-path' and '-site' is not obvious.
And 'cron.php' is also a 'path' so why do we have to use --cmd for that, but not for other paths.
All in all, I think this scripts needs to evolve a bit. It appears to be more complex than it ought to be.
Comment #27
sun+1 for simplicity.
Dries, that's awesome!
Comment #28
sunFor those interested, here's the diff.
Comment #29
gordon commentedThis is great. The main reason I did it the way I did was so that it would be more like a unix command.
The problem that I see with this new implementation is that it should run like an normal mod_rewrite() url, based on the standard drupal rewrites.
So if you are to pass http://www.example.com/module/dummy/file.php and the file 'module/dummy/file.php' exists it should include and run it.
Even if you pass http://www.example.com?q=node&page=3 should work.
It should also work for implementatations that are in subdirectories like http://www.example.com/drupal/node/123
Lastly if you have a http://www.example.com/files/images/123.jpg it should recognise that it is going to fail, and exit gracefully.
Comment #30
sunQ: Is it really possible to pass a
$_GET['q']to this shell script? I don't think so, but maybe I'm wrong. We have to investigate this.URI has to be enclosured by quotation marks now. (& is a shell command)
URI supports real files now.
Comment #31
rstamm commentedCVS ID tag broken, should be
$Id$and placed in top like all other files.Comment #32
sunAdded CVS ID.
Comment #33
moshe weitzman commentedwell, whats the status here? going into core or contrib? needs work?
Comment #34
drummI still vote for contrib. Few people will want/need to use this since it is a more advanced tool. Many people won't even be able to run it on their server environment. So why put it in the package that everyone downloads?
Comment #35
sunI thought this script would replace
cron-curl.shandcron-lynx.shin 4.7 scripts folder. Since the folder scripts won't exist for 5.0 anymore (right?) IMO this script should be provided by core in the root directory of Drupal. Drupal core should provide this easy way of cron/shell support.Comment #36
gordon commentedI am more incliended to include this in core. Not so much for the main users but for distributing Drupal in Debian, or Bryght where you want to be doing automated upgrades from a command line instead of using the web based update.php.
I see this being added to the scripts to give the a major step up for automating administration takes such as cron.
The added file is very small, and the added value more than makes up for its size.
Comment #37
sunQuestion in #30 is still open for answers. If this is not needed, it can be removed.
Comment #38
Souvent22 commentedSubscribing
Comment #39
morbus iffHas anyone had any luck doing shell access to Drupal in today's 5.0? Even something as simple as:
Which used to work in 4.7 from the shell (prints "whee") fails as a shell script against 5.0. I don't need to run a particular URL, but I do need to load all the Drupal junk inside a shell script.
Comment #40
moshe weitzman commentedhmm. Morbus' script fails for me too. odd. anyone know whats going on? this shell script seems not to work for me either. i am running drupal in a subdir, if that matters.
Comment #41
morbus iffI'm still unable to get the simple script above to work but, for my needs (which, at that moment, meant the bot.module), I did happenstance on the magic required to get it going in 5.0 and a shell. You can find the specific necessities under the --root and --url cases of http://cvs.drupal.org/viewcvs/drupal/contributions/modules/bot/bot_start....
Comment #42
gordon commentedI have made some changes to the last version which I was having a lot of problems with. The regex was just not working.
I have changed this so that it uses parse_url() and parse_str() to decode the url and populate the fields.
If the drupal system is in the root directory (ie http://www.example.com) then you can specify the path as a clean url (eg. http://www.example.com/node). But you the system is in a subdirectory then you need to specify q in the url (eg. http://www.example.com/path/to/drupal?q=node)
Comment #43
ChrisKennedy commentedThis isn't an actual patch, $Id$ is in there twice, and there are lots of coding style errors (http://drupal.org/node/318). Are the changes to bootstrap.inc still needed?
Comment #44
sunI can understand gordon so far that making a patch against a file that doesn't exist yet is actually not easy.
Here is the patch against my latest version of drupal.sh in #32.
I like the idea of using parse_url(), because this gives also an option to pass username and password, f.e. for SecureSite module.
Q: Is it possible to commit this or the previous version of drupal.sh to HEAD, so we can patch against that version?
Comment #45
ChrisKennedy commentedimo the patch needs to be developed within this issue before anything is committed. The code could use some additional comments to explain things.
Including a new file in a diff is very easy once you get the hang of it. I've added some more explanation to http://drupal.org/diffandpatch so it should be clearer about this case. Feel free to email/contact me if you have any questions/suggestions on that.
Comment #46
gordon commentedThis is a completely new file and a patch will not show any differences except that it has to add everything into the file.
Once it has been commited to core, there will be a few patches like to the watchdog module so that it indicates that the watchdog event occured from a shell, and not a web user.
As for the question about the original patch, not this is not required, and this script is completely stand alone.
Comment #47
ChrisKennedy commentedA full patch is still needed as it shows the location of the file(s); providing partial patches against previously posted files are pretty unhelpful and disorganized. You guys are really not making it easy for someone to review this issue. And if you know that changes need to be made to core for command-line Drupal you should also include them in the patch.
Comment #48
sunI've added a few definitions of server variables in the attached patch. Without these, we get PHP warnings and notices during bootstrap request_uri().
Tested against Drupal 5 and works like a breeze!
Comment #49
sunAdded
$_SERVER['SERVER_SOFTWARE'] = 'PHP CLI';in attached patch to avoid another PHP Notice in common.inc:1002 on Drupal 4.7.Now successfully tested with Drupal 4.7 and 5. I've to add that since September 2006 this script properly runs Cron on one of my Drupal 4.7 sites (productive).
Comment #50
BioALIEN commentedSubscribing...
Comment #51
dries commentedThis looks great, and I'd love to have this in core. However, the coding style needs work ...
Comment #52
sunI ran drupal.sh against Coder module to fix the coding style.
Comment #53
dries commentedHi sun, i've looked at it some more and it is starting to look real good. However, I think we can clean up the code some more. We can probably group all the verbose-code near the end of the file. Like that, we don't have to check for the verbose flag a handful of times.
Some of the verbose messages are not helpful. For example, what does "Site set to: xxx" mean? How or why is that useful information? When you say 'Site' what exactly do you mean? Elsewhere we use 'root', I think.
Secondly, the help text is a bit confusing. Say I want to create a file foo.php -- can I also run that file or does it have to be a Drupal path recognized by the menu system. Do I invoke it in the exact same way?
Enter '/cron.php' for executing cron.php (i.e. http://default/cron.php).seems to be somewhat contradictionary. Does my script 'foo.php' need to boostrap Drupal or is that taken care of?I think this is almost ready -- just trying to figure out if we need to make some final changes.
Comment #54
webchickComment #55
coreb commentedsubscribing
Comment #56
coreb commentedSorry for change status webchick, you must have submitted while i was reading...
Any chance of seeing some integration or borrowing with this project? http://drupal.org/project/drush They have the same remarkably similar goal.
Comment #57
sunComment #58
Souvent22 commentedI'd like to see this go in before working more on my patch (multi-threaded cron). I believe I will use this functionality, or have the option of using this in my patch.
Comment #59
dries commentedCommitted this to CVS HEAD. Good stuff. Thanks all. :-)
Comment #60
sunI'm urged to re-open this issue. drupal.sh was destined to live in the root directory of Drupal. It has been committed to /scripts now.
a) Either we explain this in the help/usage or
b) we have to modify the code to follow this change.
c) Or we move drupal.sh to the root directory (where it could safely live IMHO)
I'd propose c), and maybe the security team could take a quick look at it.
Comment #61
ChrisKennedy commentedThat's exactly why you should have made a patch, as I stated back in #47.
Comment #62
gordon commentedThis script was designed to live in scripts. Well actually when ever I use it I link it to /usr/local/bin
you can run it by from the root directory as scripts/drupal.sh or you can use the --root option to tell it where the root of the drupal system is.
Comment #63
sunWe definitely should inform users about how to execute this script without --root argument or this will lead to unnecessary support issues. Attached patch explains that.
Comment #64
dries commentedCommitted the patch with the clarifications. Thanks.
Comment #65
(not verified) commentedComment #66
liquidcms commentedIs it safe to say this never made it to core for Drupal 5?
Also, did anyone read #39 above - i also have the same issue whether i use this script or just right simple one on my own - no output after bootstrap run. It works in 4.7 though.
i have the following script called test1.php in my sites root folder:
and i run either from the command line or with this script as:
and my output is only
the line after bootstrap is never hit
It works in 4.7.
Peter Lindstrom
LiquidCMS - Content Management Solution Experts
Comment #67
sundrupal.sh is in D6, not 5.
Please open another issue for your problem. This one is too old and too cluttered to re-open it.
I'll try to work on the handbook pages for Setting up cron in the next days.
Comment #68
lomz commentedcan this be used to run update.php?