I need to modify the file date change using my php script. At my localhost, I used XAMPP running in Windows 7. I had no problem using PHP touch and is working properly as I want it to be.
Yet, when I uploaded it to my production, LINUX OS the PHP touch is not working anymore. I investigated it and found that, Linux, doesn't allow PHP touch or doesn't allow anybody to change file mod date.
That's why I use exec("touch filename.txt") instead and it working properly, but when I use this code
exec("touch -t 201204040000.00 filename.txt");
It doesn't do what it must, am I missing something here?
These are my references:
Linux / Unix Command: touch
3 UNIX / Linux touch Command Examples
EDIT
ls -l filename.txt
-rw-r--r-- 1 2012-11-04 12:00 filename.txt //supposed that 2012-11-04 12:00 is the original mod date of the file
If i run this code:
exec("touch filename.txt");
ls -l filename.txt
-rw-r--r-- 1 2012-11-05 11:00 filename.txt //supposed that 2012-11-05 11:00 is the current timestamp
The above code is working properly on me as everyone see.
But if i run it like this:
exec("touch -t 201204040000.00 filename.txt");
ls -l filename.txt
-rw-r--r-- 1 2012-11-05 11:00 filename.txt //The mod date doesn't changed at all.
I ran your command and it does exactly what it's supposed to do:
php -r 'exec("touch -t 201204040000.00 filename.txt");'
ls -l filename.txt
-rw-r--r-- 1 2012-04-04 00:00 filename.txt
maybe if you tell us what you expect we can help you more.
Related
I have a question about the exec function on PHP 7.0.
I write a shell script to copy/sync the files and log the details into a log file, everything happens in the tmp folder.
# /tmp/data
drwxrwxr-x 4 root www-data 4096 Apr 4 00:00 data
# /tmp/data/data.log
-rwxrwxr-x 1 root www-data 9551 Apr 4 04:19 sync.log
I tried to login as www-data user for testing the shell script, and it works fine via command line but it's not good with PHP exec as below:
exec('sh /var/www/sync.sh');
I tried to dump the data and I am sure that I can touch the .sh file.
Is there anyone have ideas about this issue?
Thanks.
I'm having trouble to run a bash file using PHP.
PHP File :
chdir('/var/www/PATH/inc/bash/');
exec('./status.sh argument, $output);
Bash File :
#!/bin/bash
echo 'test' >> /var/www/PATH/inc/bashOutput/test.txt
PHP File (ls -al handler.func.php) :
-rw-r--r-- 1 root root 461 Jul 5 11:35 handler.func.php
Bash File (ls -al status.sh) :
-rwxr-xr-x 1 root root 255 Jul 5 11:39 status.sh
Script is working using through root with SSH.
I'm not a pro on Linux.
But I think it's a problem come with the file owner.
But I have already done some damages in the past with "chown" so If it is indead the problem I would prefer some guidance from more experienced people.
Thanks for you help,
Konorr.
Script is working using through root with SSH. There is the problem. When a PHP script run via a web request it usually runs as the user www-data. In anycase <?php exec('./status.sh argument, $output);?> in a security hole. Most server admins would have this disabled.
Your other option is to put sudo in your exec function exec('sudo bash /var/www/PATH/inc/bash/status.sh'). Along with running the script with an absolute path bash /var/www/PATH/inc/bash/status.sh
Why can't you run a cron on your script?
Thanks for you answer but unfortunatly it didn't worked for me.
I search a litle more about file owners.
I did few changes
I made in these change :
chown -R www-data:www-data /var/www/PATH
usermod -a -G www-data user
chgrp -R www-data /var/www/PATH
chmod 2750 /var/www/PATH
chmod 2750 /var/www/PATH/inc/bash
It wasn't yet working till I removed the sudo from the EXEC function.
So I don't know from which point my problem was already fixed.
I followed this article : www-data permissions?
Thanks for you time and in the hope it can help someone else.
So this is my code for the raspberry pi to get a still shot from the raspicam and save it on a directory,
<?php
exec('raspistill -n -hf -o /var/www/img/image.jpg --timeout 1');
?>
I have given the ownership and the permission to read/write in that forlder using -R. so my ls -al in /var/www is this
drwxr-xr-x 3 www-data www-data 4096 Jun 19 08:05 .
drwxr-xr-x 12 root root 4096 Jun 19 05:54 ..
-rwxrwxrwx 1 www-data www-data 74 Jun 19 08:30 getImg
drwxrwxrwx 2 www-data www-data 4096 Jun 19 09:21 img
-rw-r--r-- 1 root root 70 Jun 19 10:07 index.php
getImg is the script i tried to run the script as a file like shell_exec('/bin/bash ./getImg'); that also doesn't work.
i have added /bash/bin and tried to run the script without using the script file too but that doesn't get the results.
How ever when i try to run the php file in the terminal, it creates the image as it normally should. So i figure this must be a permission issue, but what else should i do with the permissions? I have given all the rights to the directory.
EDIT
So I have found a workaround to this. since I don't know what the cause for the problem, i'd not mark this as an answer, but please vote it to appear at the top.
I now execute the script using the cgi scripts. I have created a shell script in the /usr/lib/cgi-bin/
#!/bin/bash
echo "Content-type:text/html\n"
sudo raspistill -vf -n -o /var/www/img/image.jpg --timeout 1200 --metering matrix
echo "Status: 204"
I saved this as capture and made this executable, did nothing with the permissions though.
sudo chmod +x capture
now when i open the link http://192.168.1.85/cgi-bin/capture the browser will still get me a 500 internal server error message. how ever, the image would still be created.
I would now need to get the 500 internal server error to be fixed.
[I'd add this as a comment but don't have enough points for it]
if you use the optional parameters $output and $return_var to capture the output and return value what do you get?
string exec ( string $command [, array &$output [, int &$return_var ]] )
does your command rely on environment variables that may be available when you run it as your user but not as www-data? (you can use the env command to check that)
does it still work if you run it via terminal after switching user to www-data?
I'm using the ls command via PHP and exec() and I get a different output than when I run the same command via the shell. When running ls through PHP the year and month of the date get changed into the month name:
Running the command through the shell:
$ ls -lh /path/to/file
-rw-r--r-- 1 sysadmin sysadmin 36M 2011-05-18 13:25 file
Running the command via PHP:
<?php
exec("ls -lh /path/to/file", $output);
print_r($output);
/*
Array
(
[0] => -rw-r--r-- 1 sysadmin sysadmin 36M May 18 13:25 file
)
*/
Please note that:
-the issue doesn't occur when I run the PHP script via the cli (it only occurs when run through apache)
-I checked the source code of the page to make sure that what I was seeing was what I was getting (and I do get the month name instead of the proper date)
-I also run the ls command through the shell as the www-data user to see if ls was giving different output depending on the user (the output is the always the same from the shell, that is I get the date in yyyy-mm-dd instead of the month name)
Update with answer
alias was giving me this:
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
From those aliases I was unable to find a switch that was directly responsible for the time display:
-C list entries by columns
-F append indicator (one of */=>#|) to entries
-A do not list implied . and ..
-a do not ignore entries starting with .
-l use a long listing format
However using --time-style=long-iso in PHP did fix the issue.
ls has a couple command line options for date display format. check that your command line version isn't aliased to include something like ls --time-style=locale. The PHP exec'd version will most likely not have this aliasing present and is using default ls settings.
ls output depends from current locale settings. When you run it from console on behalf yourself it uses your locale settings, but user www-data has own locale settings (which probably differ from your). So, I suggest to you specify locale settings explicitly:
exec("LC_TIME=POSIX ls -lh /", $output);
where instead of POSIX you may substitute locale which you want to use.
as the problem states..
when i do
exec("ls -ltr > output.txt 2>&1",$result,$status);
its different from the normal output. An extra column gets added. something like
-rw-r--r-- 1 apache apache 211 Jul 1 15:52 withoutsudo.txt
-rw-r--r-- 1 apache apache 0 Jul 1 15:53 withsudo.txt
where as when executed from the command prompt its like
-rw-r--r-- 1 apache apache 211 2010-07-01 15:52 withoutsudo.txt
-rw-r--r-- 1 apache apache 274 2010-07-01 15:53 withsudo.txt
-rw-r--r-- 1 apache apache 346 2010-07-01 15:55 sudominusu.txt
-rw-r--r-- 1 apache apache 414 2010-07-01 15:58 sudominusu.txt
See the difference. So in the first output , my usual awk '{print $8}' fails.
I was facing the same problem with cron. But solved it by calling
./$HOME/.bashrc
in the script. But not happening using php. If somehow i can "tell" php to "exec" from the usual environment. Any help would be appreciated.
In your login shell, ls is probably aliased so that it prints another date. This would be in your .basrc or .bash_profile.
Explicitly pass the --time-style= option to ls to ensure that it prints the date in the expected format when using PHP.
I guess you are only interested in the file names and you want to sort with reverse time.
Try this:
ls -tr1 > output.txt 2>&1
You'll get a list with only the file names, so you don't need awk at all.
Another solution is to specify the time format with "--time-style iso". Have a look at the man page
That's not an extra output, that's a difference in formatting the date. Apparently you have a different locale set in PHP and in bash ("command prompt").
(in bash, running export LANG=C or export LANG=en_US gives the result with three-letter month name)
The output of ls is heavily dependent on the environment (e.g., LANG being the important variable here). Why not use a combination of scandir, stat, and krsort?
function ls($dir_name) {
$finfo = array();
foreach (scandir($dir_name) as $file_name) {
$s = stat(join('/', array($dir_name,$file_name)));
$finfo[$file_name] = $s['mtime'];
}
krsort($finfo);
return array_keys($finfo);
}
This will be safer and a lot more efficient than shelling out to ls. Not to mention that you get the benefit of being about to customize the sorting and filter the results in ways that are difficult to do inside of an exec.
BTW: I am by no means a PHP expert, so the above snippet is likely to be incredibly unsafe and full of errors.