How do I check if a Python script is running in PHP? - php

I'm trying to check if a Python script is running in PHP, but I've no idea how.
I've tried using a database: I added an entry "request" with value response "0" and the Python script had to change that value to "1" if it was online. I couldn't get that to work so now I'm asking here

Assuming tasklist is available, this could potentially work: (this example using Windows 10)
I first launched a test2.py script:
The test2.py code is simply running:
from time import sleep
while True:
print('running');
sleep(3);
Then using this bit of php code: (I named procCheck.php)
<?php
$tasks = [];
// Use -v to include the window title info:
exec('tasklist -v 2>NUL', $tasks);
// Check the tasks array for the script we seek:
$entry = preg_grep('/(test2\.py)/', $tasks);
if (!empty($entry)) {
foreach($entry as $value) {
echo $value . PHP_EOL;
}
}
Gives this output: (one wrapped line in my console window)
Know that if there are other windows open with same script name within the window title will be found too. For example, I had the test2.py open as the active tab in Notepad++ and that entry was found as well:
Changing to some other file tab in Notepad++ only found the first entry.

Related

Change a PHP variable on the fly (while being executed)

I have a for-ever-running PHP script currently started on my machine.
I made some changes in the source code of that script: I've changed the value of one variable in global scope.
Now, if I want these changes to be applied, I could stop and restart the script, but then I would loose all the computations this script has already made. So I want to apply the code changes I made without restarting the PHP interpreter instance.
Can I do that?
What I thought about is maybe plug XDebug in the existing "php.exe" process, and try to alter the variable from there, but I don't know how to.
Another idea would be to use a software that could alter the PHP interpreter memory or symbol table, but I don't know any tool like that.
I started this script without a debuger, but I know that Java, when started with a debuger, has some option to "apply code changes without restarting the Java instance". Is there something similar for PHP interpreter?
There is a sample you might try yourself. Create the PHP file 'myfile.php' with the following code:
<?php
if (ob_get_status()) {
ob_end_clean();
}
$variable = 'Hello';
$i = mt_rand(0, 1000);
while (true) {
$i++;
echo $variable . ' ' . $i . PHP_EOL;
sleep(1);
}
Run it in command line: php -f myfile.php
You are now in my current situation: the script is running for ever, and it contains a dynamic variable $i (that I can not actually know the current value in my real world case, because that real world case has no output).
The challenge is now to change the value of $variable from 'Hello' to 'World' (which represents the variable value I changed in my real world case), but without loosing the current value of $i (that represents the currently done computations).
Remember that you cannot alter the 'myfile.php' code before running the script for the 1st time: you must run the 'myfile.php' with the exact same code as I shown, and then start the challenge.
Not within current file except invoking a function which tries to check a condition:
$variable = function() {
return date('l') == 'Saturday' ? ':)' : ':(';
};
while (true) {
echo $variable() . PHP_EOL;
sleep(1);
}
You cannot, you need to read a new value from somewhere ! You can use a database or a temporary file like this :
file1.php
<?php
file_put_contents('var.tmp','hello');
while(true) {
$var = file_get_contents('var.tmp');
print $var . PHP_EOL;
sleep(1);
}
file2.php
<?php
while(true){
$var = readline('$var > ');
file_put_content('var.tmp',$var);
}
Open 2 terminals, in the first one :
php -f file1.php
And the second one
php -f file2.php
Now you can write the value to the second terminal window and it's going to change in the first one.

php exec in the background with WAMP on Windows

with the following code i can call a php script and pass some variables into it
$cmd = 'php -f C:/wamp/www/np/myphpscript.php '.$var1;
exec($cmd);
this way my called script works, but , i need that process to be in the background , i dont want to wait for the script to finish, is there any way of doing that using wamp on windows ?
been doing some reading and some add a & at the end of the command, or a > NUL , now i noticed some of them are for linux , is there such a command for wamp on windows ? if there is please share it
EDIT: Due to the way the exec() command waits for the program to finish executing, it's very difficult to do this with vanilla exec(). I came across these solutions, and this one should work:
$rshell = new COM("WScript.Shell");
$rexec = $rshell->Run("php -f C:/wamp/www/np/myphpscript.php ".$var1, 0, false);
The WScript.Shell->Run command takes 3 arguments: the command (you can optionally add output redirection), window mode (0 = hidden), and wait it should wait to finish. Because the 3rd argument is false, this PHP should return immediately.
Original Solution: As this post suggests, you should try START /B cmd. It is virtually the Linux equivalent of cmd & in that it runs the command asynchronously, in the background, without user interaction or opening a new shell.
Because this will return immediately, PHP won't wait for it to finish, and the exec() command will not receive any output. Instead, try using shell output redirection. Your PHP given code would look like this:
$cmd = 'start /b "" php -f C:/wamp/www/np/myphpscript.php '.$var1.' >C:/wamp/www/np/output.txt';
exec($cmd);
Don't know what you are running and if you get a response to your command. But maybe it helps if you open a tab for each command. So you can see responses of each running script and at the end you can call javascript to close the tab.
You must set the variable php on windows environment !
If you have already done so skip the tutorials steps:
1. Open:
My Computer => Properties => Change Settings
2. Select the tab: Advanced
3. Click Environment Variables: Variable system
4. Click the button New
Add the name of the environment variable. Example = php
Add the path to executable php.exe. Example = D:\xampp\php\php.exe
Create a file myscript.php
The variariaveis $argc and $argv are native php.
You will notice that $ argc always carries the same value as the
result of calling count ($argv) in any case $argc is the standard
used and is a few milliseconds faster by being in memory (if that
makes any difference in performance your script).
//\n skip line
echo "\n\n";
//echo test debug
echo "Print Total Args : ";
//Print return variavel $argc
print_r($argc);
//\n skip line
echo "\n\n";
//echo test debug
echo "Print Array Args : \n\n";
//Print return variavel $argv
print_r($argv);
echo "\n";
// You can retrieve the arguments in the normal way.
$myvar_count = $argc;
$myvar_array_args = $argv;
Or if you want to set is not the environment variable, simply can call the path
Example: D:\xampp\php\php.exe myscript.php argument1 2 3 4 5
Retorn the Prompt in Windows
Total Args : 5
Array Args :
Array
(
[0] => test.php
[1] => argumento1
[2] => 2
[3] => 3
[4] => 4
)
I hope this helps! See you later!

Open Linux terminal command in PHP

I have a server running on Linux that execute commands to 12 nodes (12 computers with Linux running in them). I recently downloaded PHP on the server to create web pages that can execute commands by opening a specific PHP file.
I used exec(), passthru(), shell_​exec(), and system(). system() is the only one that returns a part of my code. I would like PHP to act like open termainal command in linux and I cannot figure out how to do it!
Here is an example of what is happening now (Linux directly vs PHP):
When using linux open terminal command directly:
user#wizard:/home/hyperwall/Desktop> /usr/local/bin/chbg -mt
I get an output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
and additional code to send it to 12 nodes.
Now with PHP:
switch($_REQUEST['do'])
{ case 'test':
echo system('/usr/local/bin/chbg -mt');
break;
}
Output:
The following settings will be used:
option = mtsu COLOR = IMAGE = imagehereyouknow!
NODES = LOCAL
And stops! Anyone has an explanation of what is happening? And how to fix it? Only system displays part of the code the other functions display nothing!
My First thought is it can be something about std and output error. Some softwares dump some informations on std out and some in std error. When you are not redirecting std error to std out, most of the system calls only returns the stdout part. It sounds thats why you see the whole output in terminal and can't in the system calls.
So try with
/usr/local/bin/chbg -mt 2>&1
Edit:
Also for a temporary work through, you can try some other things. For example redirect the output to file next to the script and read its contents after executing the command, This way you can use the exec:
exec("usr/local/bin/chbg -mt 2>&1 > chbg_out");
//Then start reading chbg_out and see is it work
Edit2
Also it does not make sense why others not working for you.
For example this piece of code written in c, dumps a string in stderr and there is other in stdout.
#include <stdio.h>
#include<stdlib.h>
int main()
{
fputs("\nerr\nrro\nrrr\n",stderr);
fputs("\nou\nuu\nuttt\n",stdout);
return 0;
}
and this php script, tries to run that via exec:
<?php
exec("/tmp/ctest",&$result);
foreach ( $result as $v )
{
echo $v;
}
#output ouuuuttt
?>
See it still dumps out the stdout. But it did not receive the stderr.
Now consider this:
<?php
exec("/tmp/ctest 2>&1",&$result);
foreach ( $result as $v )
{
echo $v;
}
//output: errrrorrrouuuuttt
?>
See, this time we got the whole outputs.
This time the system:
<?php
echo system("/tmp/ctest 2>&1");
//output: err rro rrr ou uu uttt uttt
?>
and so on ...
Maybe your chbg -mt writes additional code to stderr instead of stdout? Try to execute your script inside php like this:
/usr/local/bin/chbg -mt 2>&1
The other responses are good for generic advice. But in this specific case, it appears you are trying to change your background on your desktop. This requires many special considerations because of 'user context':
First, your web server is probably running as a different user, and therefore would not have permissions to change your desktop.
Second, the program probably requires some environmental variables from your user context. For example, X programs need a DISPLAY variable, ssh-agent needs SSH_AGENT_PID and SSH_AUTH_SOCK, etc. I don't know much about changing backgrounds, but I'm guessing it involves D-Bus, which probably requires things like DBUS_SESSION_BUS_ADDRESS, KONSOLE_DBUS_SERVICE, KONSOLE_DBUS_SESSION, and KONSOLE_DBUS_WINDOW. There may be many others. Note that some of these vars change every time you log in, so you can't hard-code them on the PHP side.
For testing, it might be simpler to start your own webserver right from your user session. (i.e. Don't use the system one, it has to run as you. You will need to run it on an alternate port, like 8080). The web server you start manually will have all the 'context' it needs. I'll mention websocketd because it just came out and looks neat.
For "production", you may need to run a daemon in your user context all the time, and have the web server talk to that daemon to 'get stuff done' inside your user context.
PHP's system only returns the last line of execution:
Return Value: Returns the last line of the command output on success, and FALSE on failure.
You will most likely want to use either exec or passthru. exec has an optional parameter to put the output into an array. You could implode the output and use that to echo it.
switch($_REQUEST['do'])
{ case 'test':
exec('/usr/local/bin/chbg -mt', $output);
echo implode('\n', $output); // Could use <br /> if HTML output is desired
break;
}
I think that the result of execution, can changes between users.
First, try to run your PHP script directly into your terminal php yourScript.php
If it runs as expected, go to your Apache service and update it to run with your own credentials
You are trying to change the backgrounds for currently logged in users... While they are using the desktop. Like while I'm typing this message. I minimize my browser and 'ooh my desktop background is different'. Hopefully this is for something important like it turns red when the reactor or overheating.
Anyway to my answer:
Instead of trying to remotely connect and run items as the individual users. Setup each user to run a bash script (in their own account, in their own shell) on a repeating timer. Say every 10 minutes. Have it select the SAME file.. from a network location
/somenetworkshare/backgrounds/images/current.png
Then you can update ALL nodes (1 to a million) just by changing the image itself in /somenetworkshare/backgrounds/images/current.png
I wrote something a while ago that does just this -- you can run a command interpreter (/bin/sh), send it commands, read back responses, send more commands, etc. It uses proc_open() to open a child process and talk to it.
It's at http://github.com/andrasq/quicklib, Quick/Proc/Process.php
Using it would look something like (easier if you have a flexible autoloader; I wrote one of those too in Quicklib):
include 'lib/Quick/Proc/Exception.php';
include 'lib/Quick/Proc/Exists.php';
include 'lib/Quick/Proc/Process.php';
$proc = new Quick_Proc_Process("/bin/sh");
$proc->putInput("pwd\n");
$lines = $proc->getOutputLines($nlines = 10, $timeoutSec = 0.2);
echo $lines[0];
$proc->putInput("date\n");
$lines = $proc->getOutputLines(1, 0.2);
echo $lines[0];
Outputs
/home/andras/quicklib
Sat Feb 21 01:50:39 EST 2015
The unit of communication between php and the process is newline terminated lines. All commands must be newline terminated, and all responses are retrieved in units of lines. Don't forget the newlines, they're hard to identify afterward.
I am working on a project that uses Terminal A on machine A to output to Terminal B on Machine B, both using linux for now. I didnt see it mentioned, but perhaps you can use redirection, something like this in your webserver:
switch($_REQUEST['do'])
{ case 'test':
#process ID on the target (12345, 12346 etc)
echo system('/usr/local/bin/chbg -mt > /proc/<processID>/fd/1');
#OR
#device file on the target (pts/0,tty0, etc)
echo system('/usr/local/bin/chbg -mt > /dev/<TTY-TYPE>/<TTYNUM>');
break;
}
Definitely the permissions need to be set correctly for this to work. The command "mesg y" in a terminal may also assist...Hope that helps.

Trouble with Named Pipes

I am new to using php and python but I have a task that I am trying to complete and the test code I have does not seem to work. Basically I am trying to get data from an html form (using php) to a python script for processing. After looking at some really useful stuff from other posts I have decided to use pipes. To test the process I have used the following code.
php code:
<?php
$pipe = fopen('Testpipe','r+');
fwrite($pipe, 'Test');
fclose($pipe);
?>
Python code:
#!/usr/bin/env python
import os
pipeName = 'Testpipe'
try:
os.unlink(pipeName)
except:
pass
os.mkfifo(pipeName)
pipe = open(pipeName, 'r')
while True:
data = pipe.readline()
if data != '':
print repr(data)
When I run the Python code I can see the pipe being created in the directory using ls -l but when I use my browser to run the php script (I am running a webserver on a raspberry pi) nothing happens. It has got me a little confused as most of the posts I read state how simple pipes are to get going. I assume on opening the browser (php script through the server) I should see the text come up in the python shell?
Any help would be appreciated.
Ok further to my original post I have modified my original code thanks to alot of trawling through the net and some really useful Python tutorials. I now have something that proves the principal of pipes although I still have to resolve the php side of things but I feel as though I'm getting there now. Revised code is below:
import os,sys
pipe_name = 'testpipe'
def child():
pipeout = os.open(pipe_name, os.O_WRONLY)
while True:
time.sleep(1)
os.write(pipeout, 'Test\n')
def parent():
pipein = open(pipe_name, 'r')
while True:
line = pipein.readline()[:-1]
print 'Parent %d got "%s"' %(os.getpid(),line)
if not os.path.exists(pipe_name):
os.mkfifo(pipe_name)
pid = os.fork()
if pid != 0:
parent()
else:
child()
This has got me on the path to where I want to go so hopefully it may be of use to someone having similar questions.
try to provide an absolute path ("/tmp/TestPipe") to be sure that both are looking to the same file.

php exec() responding differently from windows 8 metro app

I wanted to change the tile icons for desktop applications in the new windows 8 start menu.
So they would fit in with the other metro apps.
I made a simple metro app that calls a simple localhost php file
<?php
// check if the chrome is in the task list
exec('tasklist /FI "IMAGENAME eq chrome.exe" 2>NUL | find /I /N "chrome.exe">NUL');
// get a return value I can check
$runing = exec('if "%ERRORLEVEL%"=="0" echo Programm is running');
if ($runing === 'Programm is running'){
// the program is open already
echo $runing;
} else {
// the program is not running and should be opened
exec('C:\Users\Gerdy\AppData\Local\Google\Chrome\Application\chrome.exe');
}
?>
If I launch this file from chrome it echos "Programm is running".
That's great!
If I launch it from windows start and Chrome is not running, Chrome does not start.
If I exclude the if statement and just run.
exec('C:\Users\Gerdy\AppData\Local\Google\Chrome\Application\chrome.exe');
From the start menu.
It will open a new Chrome window regardless of if chrome is already open.
So I guess my question is :
What can I do that will allow my php file to check if chrome is open and if it is not , to open it?
This model actually works for any other program just not browsers.
My best guess is that it has do less with my commands and more to do with chrome itself.
It could be a target that I need to add, I don't know.
You can use Windows Management Instrumentation:
If you have not used wmic before you should install it by running wmic from cmd.exe.
It should then say something like:
WMIC Installing... please wait.
After that wmic is ready for use:
function getProcessId( $imagename ) {
ob_start();
passthru('wmic process where (name="'.$imagename.'") get ProcessId');
$wmic_output = ob_get_contents();
ob_end_clean();
// Remove everything but numbers and commas between numbers from output:
$wmic_output = preg_replace(
array('/[^0-9\n]*/','/[^0-9]+\n|\n$/','/\n/'),
array('','',','),
$wmic_output );
if ($wmic_output != '') {
// WMIC returned valid PId, should be safe to convert to int:
$wmic_output = explode(',', $pids);
foreach ($wmic_output as $k => $v) { $wmic_output[$k] = (int)$v; }
return $wmic_output;
} else {
// WMIC did not return valid PId
return false;
}
}
// Find out process id's:
if ($pids = getProcessId( "chrome.exe" )) {
foreach ($pids as $pid) {
echo "Chrome.exe is running with pid $pid";
}
} else {
echo "Chrone.exe is not running";
}
I have not tested this and just wrote it out of my head so there might be some fixing and you should check wmic's output by running it from commandline with same args to see if preg_replace() is doing it right (get pid from wmic's output).
UPDATE:
Tested and it seems that wmic does not return any status codes so updated my php function to reflect this bahavior.
UPDATE:
Now it handles multiple processes too and returns all pids as indexed array or false when no process running.
About WMI:
Windows Management Instrumentation is very powerful interface and so is wmic commandline tool. Here is listed some of WMI features

Categories