Ausführen eines Python-Skripts in WordPress

19

Ich habe eine WordPress-Installation für ein persönliches Blog und portiere nach und nach alle kleinen Webbits, die ich im Laufe der Jahre geschrieben habe, auf Seiten im Blog.

Eine solche Seite ist http://www.projecttoomanycooks.co.uk/cgi-bin/memory/majorAnalysis.py. Hierbei handelt es sich um ein einfaches Python-Skript, das eine Liste von Wörtern zurückgibt. Ich möchte dieses Verhalten in eine WordPress-Seite einbetten - Könnte mich jemand in die richtige Richtung weisen, um mit WordPress auf einfache Weise einen Punkt Python zu spielen?

BEARBEITEN - nach der wunderbaren Antwort unten bin ich viel weiter gekommen ... aber leider immer noch nicht ganz da ...

Ich habe Python, das auf dem Server ausgeführt wird ...

projecttoomanycooks server [~/public_html/joereddington/wp-content/plugins]#./hello.py 
Hello World!

und es befindet sich im selben Verzeichnis wie das aktivierte Plugin ...

Der Python-Code ... der den folgenden Code hat ...

#!/usr/bin/python
print("Hello World!")

Die PHP:

<?php
/**
 * Plugin Name: Joe's python thing.
 * Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
 * Description: A brief description of the Plugin.
 * Version: The Plugin's Version Number, e.g.: 1.0
 * Author: Name Of The Plugin Author
 * Author URI: http://URI_Of_The_Plugin_Author
 * License: A "Slug" license name e.g. GPL2
 */
/*from http://wordpress.stackexchange.com/questions/120259/running-a-python-scri
pt-within-wordpress/120261?noredirect=1#120261  */
add_shortcode( 'python', 'embed_python' );

function embed_python( $attributes )
{
    $data = shortcode_atts(
        array(
            'file' => 'hello.py'
        ),
        $attributes
    );
    $handle = popen( __DIR__ . '/' . $data['file'], 'r');
    $read   = fread($handle, 2096);
    pclose($handle);

    return $read;
}
Joe
quelle
1
Wenn es ein sehr einfaches Skript ist, würde ich es wahrscheinlich einfach in PHP als WordPress-Plugin / -Vorlage umschreiben ;-) In einigen Fällen verwenden die Leute jedoch iframes, um externe Seiten einzubetten.
Birgire
iframe es direkt? :]
Jesse
Ist das nur ein Zufall oder ist Ihr Python-Code wirklich mit PHP gemischt?
fuxia
Ich habe den Terminal-Trace eingefügt, wobei die Dateien mit dem Befehl 'more' angezeigt werden ... werden ein wenig aufgeräumt ...
Joe,

Antworten:

20

Mit können Sie ein Python-Skript popen()lesen oder schreiben (dies funktioniert auch mit jeder anderen Sprache). Wenn Sie eine Interaktion (Übergabe von Variablen) benötigen, verwenden Sie proc_open().

Ein einfaches Beispiel zum Drucken von Hello World! in einem WordPress-Plugin

Erstelle das Plugin, registriere einen Shortcode:

<?php # -*- coding: utf-8 -*-
/* Plugin Name: Python embedded */

add_shortcode( 'python', 'embed_python' );

function embed_python( $attributes )
{
    $data = shortcode_atts(
        [
            'file' => 'hello.py'
        ],
        $attributes
    );

    $handle = popen( __DIR__ . '/' . $data['file'], 'r' );
    $read = '';

    while ( ! feof( $handle ) )
    {
        $read .= fread( $handle, 2096 );
    }

    pclose( $handle );

    return $read;
}

Jetzt können Sie diesen Shortcode im Post-Editor mit [python]oder verwenden [python file="filename.py"].

Legen Sie die Python-Skripte, die Sie verwenden möchten, in dasselbe Verzeichnis wie die Plugin-Datei. Sie können sie auch in ein Verzeichnis stellen und den Pfad im Shortcode-Handler anpassen.

Erstellen Sie nun ein komplexes Python-Skript wie folgt:

print("Hello World!")

Und das ist alles. Verwenden Sie den Shortcode und erhalten Sie die folgende Ausgabe:

Bildbeschreibung hier eingeben

fuxia
quelle
Die richtige Antwort lässt aus, dass die erste Zeile des Python-Skripts, zumindest in meinem Fall, #! / Usr / bin / env Python sein muss
MikeiLL
1
@MikeiLL Das hängt vom System des Benutzers ab, also habe ich es absichtlich weggelassen.
fuxia
im Grunde ein Sicherheitsloch machen. Wenn Sie eine Pipe-Funktion für Python verwenden können, können Sie auch eine Pipe-Funktion für jeden anderen Prozess verwenden. Dies kann verwendet werden, um weitere triviale Exploits zu eskalieren.
Mark Kaplun
3

Ich habe das Beispielskript von der ersten Antwort an befolgt, aber keine Ausgabe oder Fehler erhalten.

Ich habe diese Zeile geändert:

$handle = popen( __DIR__ . '/' . $data['file'], 'r' );

dazu:

$handle = popen( __DIR__ . '/' . $data['file'] . ' 2>&1', 'r' );

und bekam dann eine "Erlaubnis verweigert" Nachricht.

Auf der Konsole lief ich

chmod 777 hello.py

hat die Seite aktualisiert und alles hat perfekt funktioniert.

Dies könnte das Problem sein, das Joe oben gesehen hat. Ich habe nicht genug Repräsentanten, um einen Kommentar abzugeben, sorry. Hoffe das hilft jemandem.

thepotoo
quelle
Machen Sie nicht die Erlaubnis 777. Machen Sie es einfach ausführbar. chmod +x filename.pywird es tun
Tessaracter
2

Hier ist ein kleines Skript, das proc_openwie oben erwähnt verwendet wird, um eine einfache Textvariable an ein Python-Skript zu senden:

add_shortcode( 'execute_python', 'execute_python_with_argv' );

function execute_python_with_argv( $attributes ){

$description = array (     
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$application_system = "python ";
$application_path .= plugin_dir_path( __FILE__ );
$application_name .= "hello.py";
$separator = " ";

$application = $application_system.$application_path.$application_name.$separator;

$argv1 = '"output to receive back from python script"';
$pipes = array();

$proc = proc_open ( $application.$argv1 , $description , $pipes );

//echo proc_get_status($proc)['pid'];

if (is_resource ( $proc ))
{
    echo "Stdout : " . stream_get_contents ( $pipes [1] ); //Reading stdout buffer
    fclose ( $pipes [1] ); //Closing stdout buffer
    fclose ( $pipes [2] ); //Closing stderr buffer

    $return_value = proc_close($proc);
    echo "<br/>command returned: $return_value<br/>";
}

$application_test = glitch_player_DIR.$application_name;

echo "<br/>Is ".$application_test." executable? ".is_executable($application_test)." ";
echo "readable? ".is_readable($application_test)." ";
echo "writable? ".is_writable($application_test)." ";

} //EOF main/shortcode function

Unten wurden einige Tests hinzugefügt, um festzustellen, ob es sich um eine Python-Datei handelt rwx. Ich denke, ein besserer Weg, das zu senden, argvwäre die Verwendung von fwrite, aber nach diesem Tutorial hat es bei mir nicht funktioniert .

Hier ist das Python-Skript, das ich verwendet habe. Wie in den obigen Kommentaren erwähnt, #!/usr/bin/env pythonkann je nach Server etwas wie erforderlich sein.

#!/usr/bin/env python

from sys import argv

script, what_he_said = argv

print "This is what you submitted: %s \n \n Isn't that amazing, man? " % what_he_said
MikeiLL
quelle