This patch allows php-eval to be used with php code from stdin.

Usage:

echo 'print "hello world!\n";' | drush php-eval -

The arg to php-eval should be '-' to indicate that the php code should be read from stdin. This could have been a test to check for an empty command, but then drush would hang waiting for input if you ran php-eval with no parameters.

There is an existing unix standard that - in place of a file means stdin; maybe this patch should have modified php-script instead, but I think this is okay as well.

The patch still needs documentation. I'm sketchy on the value of this, so someone who cares more about it will have to finish it up. For the record, I was working on this to investigate #926780: Use drush to write standard Unix scripts in php.

Comments

Title:Unix standardization for php-eval / php-script commandsAllow drush php-eval to execute code from stdin

Title:Allow drush php-eval to execute code from stdina test with a snippet

Yes, using STDIN with php-script would be appreciated too.

Meanwhile I'm wondering how to rebuild content_access
permissions in an automated way, ie, via Bash & Drush.
I'm guessing the error below isn't from the new STDIN feature?

$ thePhp=`cat <<EOF
  \\\$form_id = 'node_configure_rebuild_confirm';
  \\\$form_state['values'] = array (
    'confirm' => t('1'),
    'op' => t('Rebuild permissions'),
  );
  drupal_execute (\\\$form_id, \\\$form_state);
EOF
`
$ echo $thePhp
$form_id = 'node_configure_rebuild_confirm';
$form_state['values'] = array ( 'confirm' => t('1'), 'op' => t('Rebuild permissions'), );
drupal_execute ($form_id, $form_state);
$ alias dr
alias dr='drush -r /Applications/MAMP/htdocs/mySite'
$ echo $thePhp | dr php-eval -
WD php: call_user_func_array(): First argument is expected to be a valid callback, [error]
'node_configure_rebuild_confirm' was given in
/Applications/MAMP/htdocs/mySite/includes/form.inc on line 376.
call_user_func_array(): First argument is expected to be a valid callback, [warning]
'node_configure_rebuild_confirm' was given in
/Applications/MAMP/htdocs/mySite/includes/form.inc on line 376.

According to Pro Drupal Development p.247: "Simply provide the form ID and the values
for the form, and call drupal_execute()". But drush is nowhere to be found in that book.
(So who's the pro? :-)

Title:a test with a snippetAllow drush php-eval to execute code from stdin

Please do not change the topic of existing issues. Start new issues for new questions. Thank you.

Are you getting the error above after applying the patch in #0 manually? It has not been committed to HEAD yet.

Yes I applied the patch manually, though with a slight problem as shown below.

I don't know whether the above error is related to running via STDIN or not,
or trying to do this via Drush or not, or for other reasons.
Hence I put it here as an example of a real STDIN use-case.

$ cd /usr/local/drush
$ patch -p0  < /tmp/php-eval-from-stdin.patch
patching file commands/core/core.drush.inc
Hunk #1 succeeded at 626 (offset -50 lines).
Hunk #2 succeeded at 655 (offset -50 lines).
Hunk #3 FAILED at 856.
1 out of 3 hunks FAILED -- saving rejects to file commands/core/core.drush.inc.rej
$ cat commands/core/core.drush.inc.rej
***************
*** 851,854 ****
    }
    return $bashrc_data;
- }--- 856,859 ----
    }
    return $bashrc_data;
+ }
$ tail commands/core/core.drush.inc
  $commands = drush_get_commands();
  foreach ($commands as $key => $command) {
    // Filter out old commands that still have spaces
    if (strpos($key, ' ') === FALSE) {
      $bashrc_data .= "function $key() {\n  $drush_command $key "\$@"\n}\n";
    }
  }
  return $bashrc_data;
}

You should try the same script with php-script. I notice that your alias specifies -r but not -l. Does it work for other drush operations?

In my environment, this Drush alias works well for module downloads and make.

I use "-r" because I'm typically don't `cd` into Drupal dirs during my work.
I don't use "-l" because "--help" says that's for multisite which I don't use.
Does it do other things, and hence I should use it anyway??

With php-script (and without STDIN) I get a similar failure as above.
I'm not sure where to ask about this.
Is Drush intended to be used this way?
Is more PHP context needed - eg, to run this snippet as a specific user?
Or maybe this problem is specific to the content_access module?
Do other people (such as yourself) see the same error?
Thanks.

$ cat > /tmp/qphp.php <<EOF
<?php
  # John's dynamic PHP file, from Bash
  \$form_id = 'node_configure_rebuild_confirm';
  \$form_state['values'] = array (
    'confirm' => t('1'),
    'op' => t('Rebuild permissions'),
  );
  drupal_execute (\$form_id, \$form_state);
EOF
$ dr php-script  --script-path=/tmp  qphp
WD php: call_user_func_array(): First argument is expected to be a valid callback, [error]
'node_configure_rebuild_confirm' was given in
/Applications/MAMP/htdocs/mySite/includes/form.inc on line 376.
call_user_func_array(): First argument is expected to be a valid callback, [warning]
'node_configure_rebuild_confirm' was given in
/Applications/MAMP/htdocs/mySite/includes/form.inc on line 376.

Some more info:

I get the same error if I replace "node_configure_rebuild_confirm" with "garbage_string".
But the former string does appear in my installation:

$ cd /Applications/MAMP/htdocs/mySite
$ find . -type f -exec grep -l node_configure_rebuild_confirm {} \;
./modules/node/node.admin.inc
./modules/node/node.module
$ find . -type f -exec grep -n node_configure_rebuild_confirm {} \;
71:function node_configure_rebuild_confirm() {
79:function node_configure_rebuild_confirm_submit($form, &$form_state) {
1446:    'page arguments' => array('node_configure_rebuild_confirm'),

This quest comes when I see a common message in the status report:
"The content access permissions need to be rebuilt. Please visit this page."
(http://localhost:8888/mySite/admin/content/node-settings/rebuild)

With a front-end Curl login (http://drupal.org/node/89710),
I discover the form_id of this rebuild page:

$ grep form_id /tmp/qtmp.html
<input type="hidden" name="form_id" id="edit-search-theme-form"
  value="search_theme_form"  />
<input type="hidden" name="form_id" id="edit-node-configure-rebuild-confirm"
  value="node_configure_rebuild_confirm"  />

Often I can simply "press the button" with another Curl operation.
But rebuilding these permissions runs some Javascript with a progress bar,
and more HTTP GETs - which are hard to parse.
So I thought I'd invoke the form instead via the Drush back-end
with a php snippet read from STDIN.
Would you expect Drush to work for this?

The first thing to test is whether your alias is bootstrapping your Drupal site correctly. Does dr status show that your database is connected?

I would think that you would want to do the above operation more than once, and therefore would use drush php-script rather than php-eval from stdin.

My Drush->Drupal DB connection seems OK, can you confirm this based on info below?
Should the Drupal user shown below be "root" rather than "Anonymous"?

Can you confirm that my php-eval example above works or fails
in a known-to-be-good Drush/Drupal installation -
and whether this sort of Drush thing is expected to work in the first place ?

$ dr status
Drupal version         :  6.19
Site URI               :  http://default
Database driver        :  mysqli
Database hostname      :  localhost
Database username      :  penguinUser
Database name          :  penguinDB
Database               :  Connected
Drupal bootstrap       :  Successful
Drupal user            :  Anonymous
Default theme          :  garland
Administration theme   :  garland
PHP configuration      :  /Applications/MAMP/conf/php5/php.ini
Drush version          :  3.3
Drush configuration    :
Drupal root            :  /Applications/MAMP/htdocs/mySite
Site path              :  sites/default
File directory path    :  sites/default/files                  
$ dr vget private_key
drupal_private_key: "31e57f20e02480e048c8bbd57e400f614b07fe8b6639c4bb9de59be7552d3b67"
$ dr sql-query "SELECT uid,name,pass,mail FROM {users}"
uid name pass mail
0
1 root 8c4e600b97595baf98f089713114c391 drupal_root@localhost
3 John d41d8cd98f00b204e9800998ecf8427e drupal_john@localhost
4 Joe d41d8cd98f00b204e9800998ecf8427e drupal_joe@localhost
5 Tom d41d8cd98f00b204e9800998ecf8427e drupal_tom@localhost
$ dr -v info
Initialized Drupal 6.19 root directory at /Applications/MAMP/htdocs/mySite  [notice]
Initialized Drupal site default at sites/default  [notice]
Warning: The command name "info" is deprecated.  Please use a recommended form instead  [warning]
  (pm-releases).
No information available.  [error]
An error occurred at function : drush_pm_releases  [error]
Command dispatch complete  [notice]
$ dr -d pm-releases
Drush bootstrap phase : _drush_bootstrap_drupal_root() [0.27 sec, 2.77 MB]  [bootstrap]
Initialized Drupal 6.19 root directory at /Applications/MAMP/htdocs/mySite [0.3 sec, 3.28  [notice]
MB]
Drush bootstrap phase : _drush_bootstrap_drupal_site() [0.35 sec, 3.29 MB]  [bootstrap]
Initialized Drupal site default at sites/default [0.55 sec, 3.33 MB]  [notice]
Drush bootstrap phase : _drush_bootstrap_drupal_configuration() [0.57 sec, 3.37 MB]  [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_database() [0.65 sec, 3.38 MB]  [bootstrap]
Successfully connected to the Drupal database. [0.65 sec, 3.38 MB]  [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_full() [0.72 sec, 3.61 MB]  [bootstrap]
Drush bootstrap phase : _drush_bootstrap_drupal_login() [1.56 sec, 16.6 MB]  [bootstrap]
Found command: pm-releases (commandfile=pm) [1.59 sec, 16.59 MB]  [bootstrap]
Initializing drush commandfile: drush_make [1.59 sec, 16.6 MB]  [bootstrap]
Initializing drush commandfile: drush_make_d_o [1.59 sec, 16.6 MB]  [bootstrap]
Initializing drush commandfile: user [1.59 sec, 16.6 MB]  [bootstrap]
No information available. [2.39 sec, 16.93 MB]  [error]
An error occurred at function : drush_pm_releases [2.39 sec, 16.69 MB]  [error]
Command dispatch complete [2.4 sec, 16.67 MB]  [notice]
Timer  Cum (sec)  Count  Avg (msec)
page   1.829      1      1829.27
Peak memory usage was 17.12 MB [2.4 sec, 16.67 MB]  [memory]

Running the same php-script code in succession just gives the same error over again.
Is there another implementation of "do the above operation more than once" ?
The Pro Drupal Development book mentions a batch mode on p.560 but I'm not
sure whether this applies to Drush - no examples are given of callbacks & Drush.

Thanks for your assistance.
Please let me know if there's a better place for this topic.
I guess this exceeds the STDIN test case for php-eval ?

Title:Allow drush php-eval to execute code from stdinAllow drush php-script to execute code from stdin
Status:Needs work» Needs review
StatusFileSize
new653 bytes

I think it is reasonable to allow evaluation from stdin, but it should be supported in php-script, not php-eval. Patch included.

@John_Buehrer: If you are still having trouble with #3 - #10, try again with HEAD and post in a separate issue.

Status:Needs review» Fixed

Looks reasonable to me. Committed.

The OP sounds like he should just do drush eval "node_access_rebuild();"

Status:Fixed» Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.