bash script to run sql query on wordpress db - php

I am having a weird problem. This is a 3 step scenario.
I have a code which downloads video on my ftp directory from Youtube from a given Youtube URL
So I have a code which issues the background command to bash script which downloads the heavy videos in background (on ftp directory)
Now, when the download is completed, the bash script will call a PHP file which updates an entry in a WordPress.
The problem
The video downloads fine on my ftp directory. And the bash script also works fine until calling my PHP file for updating db entry.
Here is my bash script code
#!/bin/bash
wget -o $1 --output-document=$2 $3 &
wait
/usr/bin/php ../cron/vids_pending_download.php $4
exit
This script is working fine and calls the PHP file which has this code.
require('../../wp-config.php');
require('../inc/inc_config.php');
$vid_key = trim($argv[1]);
#$vid_key = '123_video_key';
$sql_get_vids = "SELECT vid_id, vid_name, file_size, vid_usr FROM " . $wpdb->prefix . "video_table WHERE vid_name = '".$vid_key."' ";
$vid_info = $wpdb->get_row($sql_get_vids);
if ($vid_info != null) {
echo 'video found';
} else {
echo 'video not found';
}
Now the problem is, if I supply a fixed $vid_key to my sql, it works perfect. But if I bring the $vid_key from the array from bash, it brings empty result set. However if I print the sql and paste in phpMyAdmin, it brings the record fine which means the record is there.
Looking for help. Thanks everyone.

The problem is solved. The reason was the bash script was coming too fast in return and look for the next file. While it was doing that, the actual code which is inserting into db wasn't executed. So therefore the record for the return file was not available.
This issue was happening from the actual file which submits the command to bash file.
Thanks again to all for your help

Related

Weird PHP error: exec() hangs sometimes on simple script

Heyas,
So this simple exec() script runs fine for the first two times, in trying to generate a PDF file from a webpage (using wkhtmltopdf).
It first) deletes the existing file, and second) creates the new PDF file in its place. If I run the script a second time, it deletes the file again, and then creates a new one, as expected. However, if I run it one more time, it deletes the files, creates a new one, but then the script seems to hang until the 30-second 504 timeout error is given. The script, when it works, only takes about 3 seconds to run/return. It also kills the entire server (any other local PHP sites no longer work). If I restart the PHP server, everything still hangs (with no success). Interestingly, if I run the script once, and then restart the PHP server, I can keep doing this without issue (but only generating the PDF up to two times). No PHP errors are logged.
Why would it be stalling out subsequent times?
$filePath = 'C:\\wtserver\\tmp\\order_' . $orderId . '.pdf';
// delete an existing file
if(file_exists($filePath)) {
if(!unlink($filePath)) {
echo 'Error deleting existing file: ' . $filePath;
return;
}
}
// generates PDF file at C:\wtserver\tmp\order_ID.pdf
exec('wkhtmltopdf http://google.com ' . $filePath);
I've tried a simple loop to check for the script's completion (successful output), and then try to exit, but it still hangs:
while(true) {
if(file_exists($filePath)) {
echo 'exit';
exit(); // have also tried die()
break;
}
//todo: add time check/don't hang
}
If I can't figure this bit out, for now, is there a way to kill the exec script, wrapping it somehow? The PDF is still generated, so the script is working, but I need to kill it and return a response to the user.
Solution:
Have to redirect standard output AND standard error, to end the process immediately, ie. in Windows:
exec('wkhtmltopdf http://google.com ' . $filePath . ' > NUL 2> NUL');
do you know that you can run the executable in background, like this
exec($cmd . " > /dev/null &");
This way you can immediately come out of it.

What would be the cronjob format to delete a file after a certain amount of time with php?

I am creating a system that will delete a file after an amount of time that the user specifies. The issue is, that I have no idea what the format of cronjob would be to get this function. I searched Google and all the results are how to delete all files. not 1.
You may consider writing a service using PHP.
It could look like this :
<?php
while (1){
sleep(60); //check for files to delete every minutes.
try{
//select files with delete date < now() from db.
//foreach of these files, trash them
}catch($e){
var_dump($e);
}
}
?>
And launch it in a terminal (on linux : php script.php from bash command line).

Python called from PHP but SQLite3 not working

I have this PHP script:
<?php
if($_GET["name"] != null && $_GET["name"] != ""){
$name = urlencode($_GET["name"]);
$name = htmlentities($name);
$title = urlencode($_GET["title"]);
$title = htmlentities($title);
$art = urlencode($_GET["art"]);
$art = htmlentities($art);
$output = array();
exec("python add.py $name $title $art",$output);
}
?>
and here's the add.py file:
import sys
import sqlite3
name = sys.argv[1]
title = sys.argv[2]
art = sys.argv[3]
tup = (name,title,art)
conn = sqlite3.connect('arts.db')
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS arts(name,title,art)')
c.execute('INSERT INTO arts VALUES(?,?,?)',tup)
conn.commit()
conn.close()
When the file runs there is no arts.db file in my current directory. Not only that, when I debugged my program by adding print statements every here and there I realised that my program runs till conn = sqlite3.connect('arts.db') and then exits before the statement is executed.
There is no error in my program because I used the python editor in the terminal (I use Ubuntu) and then I could execute this program successfully but this doesn't happen when I execute this from the PHP script.
If you're trying to reference an existing arts.db file, which is not in the current directory when the PHP script runs, then it's probably easiest to refer to the file by its full path, i.e. change the line...
conn = sqlite3.connect('arts.db')
...to something like...
conn = sqlite3.connect('/the/full/path/to/arts.db')
If you're trying to create a new arts.db, it's highly probable that the webserver process doesn't have permission to create the file in the current directory when the PHP script runs.
It's probably safer not to give PHP permission to write to the directory containing the PHP script[s], so create a directory somewhere else to store the file, give it the appropriate permissions, and use the full path to that directory in the script.
Update
i have figured out that i dont have permissions to write hence i
created a db using another program and created a table in it but still
for inserting values into it i require permissions, can you tell me
how to do that?
Problem is that any process spawned by the PHP script will inherit the permissions from the parent process, and will have the same limitations.
On recent versions of Ubuntu, the /var/tmp directory can always be written to by any user, so you could put it there with...
conn = sqlite3.connect('/var/tmp/arts.db')
...or you can put it anywhere else by modifying the permissions, with...
$ sudo chgrp www-data /the/full/path/to/directory
$ sudo chmod g+ws /the/full/path/to/directory
Of course, this means there's not much point in using a seprate Python script, so you may as well do it all in PHP.

passing php variable to bash script that uses shflags

I am trying to make a PHP program triggered by a web submit tell a bash script to run with a single command line parameter. I am using the shflags command line parser for bash.
The pertinent part of the PHP script is as follows:
// generate unique filename
$destinationFolder = Mage::getBaseDir('media') . DS . 'webforms' . DS . 'xml';
$filename = $destinationFolder . DS . $result->getId().'.xml';
// create folder
if (!(#is_dir($destinationFolder) || #mkdir($destinationFolder, 0777, true))) {
throw new Exception("Unable to create directory '{$destinationFolder}'.");
}
// export to file
$xmlObject->getNode()->asNiceXml($filename);
// define parameters to pass
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
}
}
?>
The bash script (xform.sh) (just a test script) is as follows.
#!/bin/bash
. ./shflags
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/$$".txt"
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
DEFINE_string 'xmlfilename' 'test' 'filename of current x.xml file from webforms' 'Z'
FLAGS "$#" || exit 1
eval set -- "${FLAGS_argv}"
echo "xml file was" ${FLAGS_xmlfilename} >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
The bash script works correctly from the command line, i.e.
$xform.sh --xmlfilename 1.xml
writes "xml file was 1.xml" to the foo.txt file.
When the PHP script is triggered from the web, the first part works correctly, i.e. it writes "foo" to the two target files, foo.txt and $$.txt. However, the xmlfilename variable is not coming along, and I really need that file name to be passed to the command line! (Note I should not need to use escapeshellarg because the file name is generated by my PHP program, not by user input.)
I have checked all the file permissions I can think of. xform.sh and shflags are both members of the www-data (Apache) group, owned by Apache, and a+x.
My suspicions are that the problem is related either to a) my PHP exec syntax or b) file permissions. Everything works as intended except the bit after xform.sh in this line!
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
UPDATE:
I've narrowed the problem some more by isolating the problem with some test code. With:
$script="echo";
$xmlfilename="$filename";
$target=">> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt";
exec ("$script $xmlfilename $target");
...
PHP correctly writes the $filename to foo.txt, so $script works when value is "echo" and $filename works too.
When I set $script to a different simple form of the xform script that (only) writes the data to the file, that also works correctly.
So the problem is specifically with something that happen when PHP tries to write the $filename as a command line variable. Does a script run by Apache need more permissions than usual if it includes a command line variable?
Sigh.
In your exec() call you have the flag as --xmlfile but you are calling it from the command line as --xmlfilename

PHP, problem with exec...how do I make sure the execution is working?

I am uploading a video, which is supposed to generate three screenshot thumbnails. I have the same upload code running in both admin and front-end, but for some odd reason the thumb is only being generated when I upload from front end, and not from backend...
My directory structure
root/convert.php (this is the file running through exec call)
(the following two files are the upload files running in user-end and admin-end respectively)
root/upload.php
root/siteadmin/modules/videos/edit.php
I believe convert.php is not being run from admin-side for some reason. The command is something like:
$cmd = $cgi . $config['phppath']. ' ' .$config['BASE_DIR']. '/convert.php ' .$vdoname. ' ' .$vid. ' ' .$ff;echo $cmd;die;
exec($cmd. '>/dev/null &');
And echoing out the exec $cmd, I get this:
/usr/bin/php /home/testsite/public_html/dev/convert.php 1272.mp4 1272 /home/testsite/public_html/dev/video/1272.mp4
How do I make sure convert.php is being run?
EDIT: OK, now I am sure it is not being executed from admin-side, any ideas why?
http://php.net/manual/en/function.exec.php
"return_var" - If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
Another way to determine if exec actually runs the convert.php file, add some debugging info in convert.php (e.g. write something to a file when the covert.php script starts).
Just an Idea
you could print "TRUE" in the convert script when it runs successfully.
don't add >/dev/null &
check the return value of exec
$value = exec($cmd);
if($value == 'TRUE')
// did run sucessfully
}
chmod 755 convet.php
you also make sure the first line of convert.php is:
#!/usr/bin/php
check the full path of php cli executable.
Also make sure convert.php las unix line ending ("\n")

Categories