I have a C program that I wrote called convert3to5, originally written for CentOS / Fedora 32bit system in early 2010. I am moving it to new CentOS 6.x 64bit system host.
From a CentOS Putty console I can run the convert3to5 command just fine; here is a sample of it running from my console:
[root#cloud convert3to5]# ls
CircleStar convert3to5 Convert3To5.txt test.tif
[root#cloud convert3to5]# ./convert3to5 /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif
TIFFReadDirectory: Warning, /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif: wrong data type 7 for "RichTIFFIPTC"; tag ignored. Image has an undefined fillorder - using default: MSB2LSB
The above is a normal completion of convert3to5 and I get a SV-DIS160217B.bmp that is placed in /var/www/webadmin/data/www/mydomain.com/uploads/ So running it from console works fine.
Question - I am attempting to run the same exact command from PHP using the exec(command, output, return) command as follows:
chdir($sv_path.$c3to5_path); //change our working directory to "/convert3to5" directory
$command = "./convert3to5 $targetFile 2>&1";
$result = exec($command, $output, $return);
// the output of the above command - is a .bmp file it will be placed in the same path as the input .tif file
I get the following $result:
ERROR: Unable to convert
/var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif to 5
color BMP file: Open file Error: Tiff_3_to_BMP_5_.lut!
My convert3to5 does need to open Tiff_3_to_BMP_5_.lut
Why does it find Tiff_3_to_BMP_5_.lut when I run convert3to5 from a console prompt but not from PHP exec(...) in both cases my pwd shows that I am in
[root#cloud convert3to5]# pwd
/var/www/webadmin/data/www/mydomain.com/myView/convert3to5
I have also verified pwd is correct from my PHP script after the
chdir($sv_path.$c3to5_path);
Tiff_3_to_BMP_5_.lut is in CircleStar directory - the path to CircleStar is /var/www/webadmin/data/www/mydomain.com/myView/convert3to5/CircleStar
Summary: ./convert3to5 works while PHP exec('convert3to5 ..) does not appear to work.
Can anyone suggest the difference and how to fix and/or debug?
Thanks
You're running the console from the convert3to5 directory, and I suspect your old C program used a relative path to the .lut file, possible relative to the .tif?
What if in the console example you did
cd ../..
./path/to/convert3to5/convert3to5 /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif
Might be related to $targetFile. Print that and see if it's the full path.
Finally, run
/full/path/to/convert3to5 fullTargetPath
If that works, then as a workaround, if you just do exec('/full/path/to/convert3to5 $fullTargetPath, ..) it should behave like the console.
Per my above comment to wonton:
From the console I was running as root (so fully privileged). I supposed my PHP script will run as the "apache" user on the server?
Here was the problem I believe: I looked at the CircleStar directory privileges where the Tiff_3_to_BMP_5_.lut file exists. CircleStar had rw-r--r-- (0644) when running as root from console this allowed my convert3to5 program to find and open Tiff_3_to_BMP_5_.lut file just fine. However not the PHP exec(...) once I changed the privilege on CircleStar to rwxr-xr-x (0755) PHP exec(...) ran fine!
So ultimately it was a permission issue.
Related
EDIT - Adding new info at the top for visibility. The www-data user can't use the exec() command. All attempts return a 127 error.
I setup a simple script that is just this
<?php
$res = exec("echo EXEC", $res1, $res2);
var_dump($res);
var_dump($res1);
var_dump($res2);
?>
When executed via the application (which of course runs as www-data) this returns the 127 error code.
When executed via this command it runs flawlessly sudo -u root php testExec.php
When executed via this command it again returns the 127 error code sudo -u www-data php testExec.php
Original Question
I can only seem to get the error code 127 back when trying to use the exec command in php. I'm trying to use the https://github.com/rialto-php/puphpeteer package to generate pdfs and it was working flawlessly but I can't find what changed that is causing it to fail now.
I've been using /usr/local/.nvm/versions/node/v14.2.0/bin/node as the path to node but I also tried copying it here /node/v16.14.2/bin so I could give the entire directory structure execute permissions. In either/both places node is owned by www-data (the user that php runs as) and has execute permissions (755).
Running '/node/v16.14.2/bin/node' '/var/www/html/vendor/nesk/puphpeteer/src/get-puppeteer-version.js' (the initial command that puphpeteer generates) from the command line works just fine and returns the expected result "5.5.0" so node is there and executable and the get-puppeteer-version script exists.
After troubleshooting that I decided to just test exec and discovered that that doesn't work for any commands. I've tried just running exec("date"); and exec("echo EXEC") and these also return the same exit code 127.
The disable_functions ini setting is empty (confirmed via empty result from ini_get('disable_functions')). Safe mode is not enabled (confirmed via false result from ini_get('safe_mode')).
If anyone has any insight into why exec won't work at all would be great!
Environment:
Ubuntu 18.04.4
PHP 8.1
So after further investigation.. I found that this was indeed a permissions issue. I had double checked that node and everything in the /bin folder had appropriate execute permissions..
What I had missed (and am not sure how it got changed) was that the /bin folder itself didn't have the appropriate execute permissions. Adding those immediately fixed my issue.
My website is about copying files. Instead of copy the files to avoid to much time and server lagging, I decided to use overlayfs. The code mount the folder to the location specified in the terminal using the PHP interpreter. But, when I run the php script from Apache the script does not mount the overlay. And the worst is that there is no error output so I can debug what's wrong. I checked the php error log, no output about what happened.
The destination i'm mounting the overlayfs is to another user. For that I need root to execute the mount command. To be able to run the code without using root nor sudo, I took a look at this question. I created the c code, compile it and set the proper permissions (root.root, rwsr,sr...). I ran the code in a php file:
<?php
// filename over.php
print shell_exec("whoami")."\n";
print shell_exec('/var/www/vhosts/user/deployment/exec "sudo mount -t overlay overlay -o lowerdir=/var/www/vhosts/user/deployment/template5_dev,upperdir=/var/www/vhosts/user.deve/httpdocs,workdir=/var/www/vhosts/user/deployment/overlay-work /var/www/vhosts/user.deve/httpdocs"');
What the code does is print the actual user name (to make sure I have an output, to see if the code executed) then merge the folders. The file /var/www/vhosts/user/deployment/exec is the c program then I pass the code to execute as argument.
In the terminal I run: php -f "/var/www/vhosts/user/httpdocs/over.php". I check the merged folder I can see it works. And the output is user.
Then I unmount the overlay sudo umount /var/www/vhosts/user.deve/httpdocs.
I access the php script via the browser, I got the output user but the folder does not merge. I ctrl-f5 multiple times but nothing, no error, no error in log nothing.
I changed the command to shell_exec('/var/www/vhosts/user/deployment/exec "sudo mkdir /var/www/vhosts/user.deve/httpdocs/nouvo"');, the sudo created the folder from the browser.
I noticed that only the mount command does not run properly.
What could be the reason the sudo mount command does not run by apache, and even if there was an error, doesn't it print out the error?
I just take a look at /var/log/kern.log. I can see the mount command got executed from the web-browser. But the log is different from the one the ones executed in the terminal.
From the web-browser:
kernel: [ 149.465459] overlayfs: filesystem on '/var/www/vhosts/user.deve/httpdocs' not supported as upperdir
kernel: [ 151.629192] overlayfs: filesystem on '/var/www/vhosts/user.deve/httpdocs' not supported as upperdir
kernel: [ 153.453612] overlayfs: filesystem on '/var/www/vhosts/user.deve/httpdocs' not supported as upperdir
From the terminal after executing from the browser:
kernel: [ 312.858797] overlayfs: upperdir is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.
kernel: [ 312.858804] overlayfs: workdir is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.
I just don't get the log from the browser since the script is same.
I'm trying to execute with PHP a command (rsync) to copy folders and files from a remote server to a local folder.
This is the code I wrote in php. Command WORKS in SSH (local Terminal and remote with putty.exe), copying correctly the folders and the files.
But it doesn't work in PHP. What can I do? Do you know a better(secure/optimal) way to do this?
exec("echo superuserpassword | sudo -S sshpass -p 'sshremoteserverpassword' rsync -rvogp --chmod=ugo=rwX --chown=ftpuser:ftpuser -e ssh remoteserveruser#remoteserver.com:/path/files/folder /opt/lampp/htdocs/dowloadedfiles/", $output, $exit_code);
EDIT:
I had read this guide to create a link between my server and my local machine.
Now I can login with ssh in my remote machine without password.
I changed my command:
rsync -crahvP --chmod=ugo=rwX --chown=ftpuser:ftpuser remote.com:/path/to/remote/files /path/to/local/files/
This command works too in terminal, but when I send it with exec php command, it fails again, but I got another different error: 127.
As MarcoS told in his answer, I checked the error_log.
The messages are this:
ssh: relocation error: ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: remote command not found (code 127) at io.c(226) [Receiver=3.1.1]
Well, after lot of try/error, I finished to cut the problem in the root:
I readed this guide (like the last one, but better explained) and I changed the php file that execute the rsync command to the remote server (where files are located) and run the rsync.php file there, and it worked perfectly.
To execute in the machine with the files (the files to copy and the rsync.php)
1.- ssh-keygen generates keys
ssh-keygen
Enter an empty passphrase and repeat empty passphrase again.
2.- ssh-copy-id copies public key to remote host
ssh-copy-id -i ~/.ssh/id_rsa.pub remoteserveraddressip(xxx.xxx.xxx.xxx)
The rsync.php file:
exec("rsync -crahvP /path/in/local/files/foldertocopy remoteuser#remoteserveraddress:/path/in/remote/destinationfolder/", $output, $exit_code);
After all of that, navigate to the rsync.php file and all must work. At least worked for me...
I suppose you are experiencing identity problems... :-)
On a cli, you are running the command as the logged-in user.
On PHP, you are running the command as the user your web server runs as (for example, apache often runs as www-data, or apache user...).
One possible solution I see (if the above is the problem real cause), is to add your user to web-server group...
I'd also suggest you to check the web-server error logs, to be sure about the real cause of the problem... :-)
I have the following PHP code that is run when a user clicks a button on a local intranet page to run some Node JS commands. e.g.
exec('npm install', $output);
$output = implode(PHP_EOL, $output);
echo $output;
But the command doesn't seem to get run... It does if I type the command into the command prompt and run it...
I don't see any errors and NodeJS is set as a system variable in the Path so it should know what grunt is... Any ideas? Other commands, e.g. whoami run fine.
Any ideas?
I'm on Windows 7.
Update: Based on the comments below I can now get an error with:
exec('npm install 2>&1', $output, $returnCode);
$output = implode(PHP_EOL, $output);
echo $output . ' ' . $returnCode;
And this is the error:
TypeError: Cannot call method 'get' of undefined at C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:310:23 at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:80:7 at Array.forEach (native) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:79:13 at f (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\once\once.js:16:25) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:108:14 at Conf. (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:179:14) at Conf.next (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\lib\load-prefix.js:48:20) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\mkdirp\index.js:37:53 at Object.oncomplete (fs.js:107:15) C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:33 throw new Error('npm.load() required') ^ Error: npm.load() required at Object.npm.config.get (C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:33:11) at exit (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\error-handler.js:49:27) at process.errorHandler (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\error-handler.js:316:3) at process.emit (events.js:95:17) at process._fatalException (node.js:272:26) 7
So it looks like the PHP knows where NodeJS and NPM is... but can't run it?
If I do whoami in the PHP I get: nt authority\iusr
But if I do it from the command prompt then I get: dom\cameron
I wonder if it's because PHP runs it as a different user to when I run it directly in the command prompt...
Okay I've managed to fix this!
Basically you need to run the website (where the PHP file lives) as the same user as where NodeJS is run from!
To achieve this I did the following in IIS:
1.) Find the website
2.) Choose basic settings
3.) Click the connect as... button
4.) Choose 'specific user'
5.) Enter `dom/cameron` and my password
6.) Restart IIS
If anyone has any ideas for how to get NodeJS running for the default nt authority\iusr then feel free to post an answer :)
You defined npm in WINDOWS path, but did PHP recognize it?
I suggest you should test it with writing the full NPM path in the exec. If it works, than you should call putenv() with correct parameters before executing npm install..
So first try:
exec('C:\npm-test\npm install', $output);
$output = implode(PHP_EOL, $output);
echo $output;
And if it works, use the putenv() command before calling exec(). Example:
putenv("npm='C:\npm-test\npm'");
//and then exec(...)
The error you're getting indicating that an object is not defined. It's quite possible that a module is simply not loading because you're not running the script from the correct location, and relative links to some include are not working. Running as the correct user might fix it. Or try changing to the correct directory before running the node script. Or change the location of the links inside the node script.
I am trying to convert .docx file to .html using php shell_exec in CentOS 6.5
My php code:
$command = "libreoffice --headless -convert-to html resume.docx 2>&1";
$result = shell_exec($command);
echo $result;
When I run the index.php at http://localhost/converter/ it gives me:
javaldx: Could not find a Java Runtime Environment! Warning: failed to read path from javaldx /usr/lib64/libreoffice/program/soffice.bin X11 error: Can't open display: Set DISPLAY environment variable, use -display option or check permissions of your X-Server (See "man X" resp. "man xhost" for details)`
while in terminal it is working perfectly:
cd /var/www/html/converter/
libreoffice --healdess -convert-to html resume.docx
here it creates resume.html in my /var/www/html/converter/.
Hi i have the same problem, i want to convert PDF's from DOCS created with PHP, i'm using OpenSuse 12.3 with LibreOffice, tried many things, finally i detect that the error is in folder:
1.- First check that you don't have disabled shell_exec in php.ini, and open_basedir don't restrict your access folders.
2.- Run the command as a simple user in shell (terminal)
export HOME=/tmp && soffice --headless --convert-to pdf --outdir /srv/www/htdocs/ /srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx
3.- If it works, you only have to put the correct folders in your code, when i run this code in PHP, it show me a blank page, so i check the access_log of apache for any hint:
[Java framework] Error in function createSettingsDocument (elements.cxx).
javaldx failed!
Warning: failed to read path from javaldx
terminate called after throwing an instance of 'com::sun::star::uno::RuntimeException'
Note: my error was in using export HOME=/tmp, i checked that the folder in root system has 777 for tmp, but the problem was that apache don't acces to it, maybe search for a relative folder of the script, but after test many things i only put a folder with permissons for wwwrun HOME=/srv/www/htdocs/folder_with_777
This is my final code, that works..
<?php
function word2pdf()
{
echo "Procesando";
$result = shell_exec('export HOME=/srv/www/htdocs/Creecimientos/sic/ && soffice --headless --convert-to pdf --outdir /srv/www/htdocs/Creecimientos/sic/ /srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx');
echo $result;
}
word2pdf();
?>
In fact, it prints: convert srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx -> /srv/www/htdocs/Creecimientos/sic//8_Pagare_CreePersonas.pdf using writer_pdf_Export, after succes.
I made other changes before in desesperate mode, but none of them solved the problem, tried to change owner to soffice wich found it witch $ ls -l $(which libreoffice), tried with 777, etc..
/* This command will work on centos 6 /7 with installation of libreoffice headless package */
First install package on centos as :
yum install libreoffice-headless
/* following code work to extract text format from */
<?php
$result = exec("export HOME=/tmp/ && /usr/bin/libreoffice --headless --convert-to txt:Text --outdir /tmp filePath");
var_dump($result);
?>
Most likely the user that LibreOffice is ran as, does not have a writeable home directory so LibreOffice fails to create it's config directory and then it cannot create it's config files and then fails to load Java, because it cannot write the default config. A bit silly I know.
Try adding this parameter: -env:UserInstallation=file:///tmp/whateverhere
I don't have enough reputation to comment on TD_Nijboer's answer, but the answer to his specific problem appears to be that soffice needs to be able to read & write config information somewhere. The first place it tries to do this is the libreoffice directory in ~/.config ('~' means "the current user's home directory").
In Debian, by default, the www-data user has the home directory /var/www, and does not have write permission there.
If you make sure it has permission to either create ~/.config itself, or libreoffice within an existing ~/.config, I expect it will work.
2 things, 1st the command is soffice --headless,
2nd i have an similar javaldx error and it has to do with permission.
when executing as root it works fine, but php executes as www-data.
if anybody knows a good way to execute libreoffice from php please let me know.
as i'm getting an error code 77 saying:
[Java framework] Error in function createSettingsDocument (elements.cxx).
javaldx failed!
Warning: failed to read path from javaldx