Cron job fails in CPanel with % character in URL [duplicate] - php

I have a cron issue with curl:
curl -w "%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
works great and add a line in log file with total_time.
But the same line with cron doesn't do anything.
It's not a path problem because curl http://myurl.com >> ~/log works.

% is a special character for crontab. From man 5 crontab:
The "sixth" field (the rest of the line) specifies the command to be
run. The entire command portion of the line, up to a newline or a
"%" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile. A "%" character in the
command, unless escaped with a backslash (\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.
So you need to escape the % character:
curl -w "%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
to
curl -w "\%{time_total}\n" -o /dev/null -s http://myurl.com >> ~/log
^

Related

Send my .php output to a curl command that messages me on telegram using a bot

I have the following cron executed every few minutes:
*/8 * * * * /usr/local/bin/php -f /home/xxx/yyyy.php >> /home/xxx/zzzz.log
Currently its output is being stored in the .log file. But I want to be able to send the output to me as messages via a telegram bot.
I made a bot already and have the api keys, but I'm unsure how to connect them.
On the telegram api docs, it says I can use curl to have the bot send me a message by doing the following in a bash file:
#!/bin/bash
CHATID="1234"
KEY="abcd"
TIME="10"
URL="https://api.telegram.org/bot$KEY/sendMessage"
TEXT="Hello world"
curl -s --max-time $TIME -d "chat_id=$CHATID&disable_web_page_preview=1&text=$TEXT" $URL >/dev/null
adding curl after >> obviously doesn't work. How would this be done?
Assign the output of the PHP script to the TEXT shell variable
CHATID="1234"
KEY="abcd"
TIME="10"
URL="https://api.telegram.org/bot$KEY/sendMessage"
TEXT=$(usr/local/bin/php -f /home/xxx/yyyy.php)
# URL-encode some special characters
TEXT=${TEXT//%/%25}
TEXT=${TEXT//&/%26}
TEXT=${TEXT//=/%3D}
TEXT=${TEXT// /%20}
curl -s --max-time $TIME -d "chat_id=$CHATID&disable_web_page_preview=1&text=$TEXT" "$URL" >/dev/null
Put the above in a shell script and run that from cron instead of running the PHP script directly.
If you also want it sent to the log file, you can use the tee command:
TEXT=$(usr/local/bin/php -f /home/xxx/yyyy.php | tee -a /home/xxx/zzzz.log)
You can redirect your cron output to a script, or a command by using a pipe (|)
here is an example :
*/8 * * * * /usr/local/bin/php -f /home/xxx/yyyy.php | tee /home/xxx/zzzz.log | /home/xxx/telegram.sh
This will write the output of your command to /home/xxx/zzzz.log and send it to the stdin of the script.

shell errors running php exec

I have a PHP script that executes a shell command to find the common items between two files given. This is the beginning of my PHP script:
$E7Bonded_File = "/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv";
$E7Single_File = "/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv";
$E7Common_File = "/opt/IBM/custom/NAC_Dslam/junk/Common_tn_SingleBonded_E7_cust_stats.csv";
//only do this once, with old single/bonded filenames. This will be a list to add to the existing Common file.
exec ("comm -12 <(cut -d ',' -f2 $E7Single_File| sort) <(cut -d ',' -f2 $E7Bonded_File| sort)", $outputCommon);
I see this error message when I run the script:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `comm -12 <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv| sort)'
I checked, and the parentheses look ok for my exec() line.
When I run the shell command at the command line it returns a listing of numbers like I expect:
comm -12 <(cut -d ',' -f2 junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
I looked online and I seem to be using exec() correctly. I want the numbers returned to be stored as an array, $outputCommon.
Any ideas about this error message?
*********Update on answer***************
My solution wound up being a combination of both mario and miken32/my co-worker
Adding #!/bin/bash at the top of my php script, and
Adding /bin/bash -c as follows:
exec("/bin/bash -c /opt/IBM/custom/NAC_Dslam/Common_list.sh", $outputShell);
After I moved the comm part to a shell script:
Common_list.sh:
#!/bin/bash
comm -12 <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
This error typically comes up for non-bash shells, which don't support <() expression pipes.
On Ubuntu/Debian servers the default /bin/sh is typically dash.
Check for symlinked binaries:
me#snip:~$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jul 16 2017 /bin/sh -> dash
Or as #theotherguy mentioned, bash runs as restricted_shell when started as sh.
See $_ENV[SHELL] on what Apache/PHP use as default. Change environment vars.
Either adapt that, or wrap the shell_exec cmdline with /bin/bash -c '…'.
Probably the easiest solution would be to make this into an executable script on the server:
#!/bin/bash
if [[ ! -r "$1" ]] || [[ ! -r "$2" ]]; then
printf "File not found\n" >&2
exit 1
fi
comm -12 <(cut -d ',' -f2 "$1"| sort) <(cut -d ',' -f2 "$2"| sort)
And then call that from PHP:
$E7Bonded_File = escapeshellarg("/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv");
$E7Single_File = escapeshellarg("/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv");
//only do this once, with old single/bonded filenames. This will be a list to add to the existing Common file.
exec ("/usr/local/bin/your_script.sh $E7Single_File $E7Bonded_File", $outputCommon);
Always escape your shell arguments with escapeshellarg() even if you think they're safe.
when checking the script with a linter, it complains that:
comm -12 <(cut -d ',' -f2 junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
^-- SC2039: In POSIX sh, process substitution is undefined.
this happens when I define shebang #!/bin/sh, while #!/bin/bash does not complain... therefore the answer might be, to run the script with /usr/bin/bash. escapeshellarg() is indeed useful.
...
try shell_exec(), simply because exec() should not invoke any shell. the one returns the output as string and the other can return an array.
alternatively, you can explicitly invoke bash with exec():
exec('/bin/bash -c " command "', $stdOut);
So in case anyone else still needs to get substitution working in command execution in PHP, there is super dumb simple thing to do:
$a = 'Hello substitution';
var_dump(shell_exec("bash -c 'cat <(echo $a)'"));
Results in:
string(19) "Hello substitution
"
Which is expected/desired.

exec not properly executing php command centos 7

using
xls2csv -x /usr/share/nginx/html/price_list_EN.xls -s cp1252 -d 8859-1 > /usr/share/nginx/html/price_list_EN.csv
in linux commandline it works and exports it correctly, but if I use it on php
$transf2 = "xls2csv -x /usr/share/nginx/html/price_list_EN.xls -s cp1252 -d 8859-1 > /usr/share/nginx/html/price_list_EN.csv";
exec($transf2);
a file named price_list_EN.csv appears but it remains empty...
Try to execute your command like this from shell
su -s /bin/bash -c "xls2csv -x /usr/share/nginx/html/price_list_EN.xls -s cp1252 -d 8859-1 > /usr/share/nginx/html/price_list_EN.csv" www-data(your webserver user name)
then you debug the error

PHP exec() works in command line but not in web

I'm trying to use jarun's "googler" in a PHP script in order to search YouTube and find the URL of the first result. The command I'm executing is googler --np --json -C -n 1 -w youtube.com -x <name of youtube video>, and it works perfectly on my local machine. Here is my code:
<?php
exec("googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine", $results);
var_dump($results);
?>
When I execute this in the command line, it works perfectly as it should, but when I do it via a web browser or a GET request, it does not work. I am aware that it is being executed as another user. In my case, it's the user www-data, so I gave that user full sudo permissions without a password, and did the following commands:
sudo -u pi googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine
as well as
su - pi -c 'googler --np --json -C -n 1 -w youtube.com -x thomas the dank engine'
neither of these worked. Does it have to do with googler? What am I doing wrong?
When adding 2>&1 to the command, I get the following error message:
stdout encoding 'ascii' detected. googler requires utf-8 to work properly. The wrong encoding may be due to a non-UTF-8 locale or an improper PYTHONIOENCODING. (For the record, your locale language is and locale encoding is ; your PYTHONIOENCODING is not set.) Please set a UTF-8 locale (e.g., en_US.UTF-8) or set PYTHONIOENCODING to utf-8.
Try putting:
putenv("PYTHONIOENCODING=utf-8");
in the script before calling exec(). googler apparently requires the locale or this environment variable to be set.
You must remove exec from the disable_functions parameter in the php.ini file for your server module installation of PHP (which is separate from your CLI installation). It is typically disabled by default for the server module.

Using wget with shell_exec and at command?

I've been struggling with shell_exec PHP function and at linux command for 2 days.
To make it short, this works:
shell_exec('/usr/bin/at 09:32 <<EOF
touch /var/www/website/hello.txt
EOF'
);
this doesn't:
shell_exec('/usr/bin/at 09:32 <<EOF
wget -O - -q -t 1 "http://192.168.56.101/website/test.php?param=hello" >/dev/null 2>&1
EOF'
);
Why ?
(note: the code above does work in console)
Thanks in advance.
Ok I've got it at last !!
For those who are interested the pb comes that the wget command also need to be invoked with the full path (ie: /usr/bin/wget).
What misleaded me is that the touch command doesn't need it. It's weird but anyway here's the working code:
shell_exec('/usr/bin/at 09:32 <<EOF
/usr/bin/wget -O - -q -t 1 "http://192.168.56.101/website/test.php?param=hello" >/dev/null 2>&1
EOF'
);

Categories