我正在运行一个生成符号链接的 PHP 脚本。
要确认它是哪个用户:
file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
echo "running as user '" . $user . "'";
var_dump( exec('whoami'));
像这样跑...
$ php script.php
运行正确,所有符号链接均已建立,输出为:
running as user '999'string(5) "admin"
通过 shell 脚本运行:
#!/bin/sh
php /path/to/script.php
给出以下输出并且不起作用:
PHP 警告:symlink():第 8 行 /path/to/script.php 中的权限被拒绝,以用户“999”string(5)“admin”运行
我不确定两者之间有什么区别,因为它们运行的用户是相同的。
关于如何使它们都具有正确的符号链接权限有什么建议吗?
cat /proc/version
给出:
Linux version 2.6.39 (root@cross-builder) (gcc version 4.6.3 (x86 32-bit toolchain - ASUSTOR Inc.) ) #1 SMP PREEMPT Thu Oct 31 21:27:37 CST 2013
这是我可以为任何类型的发布信息生成的唯一输出。
全部代码:
$files = scandir('/volume1/dir1');
$base = "/volume1/";
foreach($files as $file) {
$f_letter = $file{0};
$new_path = $base . "ByLetter/" . strtoupper($f_letter) . "/" . $file;
if(ctype_alpha ($f_letter) && !is_link($new_path)) {
var_dump($base. "TV/" . $file);
var_dump($new_path);
symlink ($base . "TV/" . $file , $new_path);
}
}
两种方法的 var dumps 给出相同的输出。
答案1
尝试使用绝对路径。该代码unlink("testFile");
在当前工作目录中查找文件。 pwd 根据当前工作目录而变化。所以使用unlink("/path/to/testFile");
答案2
我拿了您发布的代码,认为这是一个有用函数的开始,对其进行了调整,并且无法让它失败(可能是因为我的用户对两个路径都有写访问权限)。我确保添加了大量检查,以便让您知道是否出现问题。如果您仍然遇到同样的问题,请告诉我。请务必记住,如果您通过 CLI 执行脚本,则该脚本具有与您相同的权限,但是如果通过 Web 服务器执行,则它具有 Web 服务器用户的权限(例如www-data
)
<?php
/**
* Creates an index of the files in the specified directory, by creating symlinks to them, which
* are separated into folders having the first letter.
* WARNING - this will only index files that start with alphabetical characters.
* @param $directory_to_index - the directory we wish to index.
* @param $index_location - where to stick the index.
* @return void
*/
function create_file_index($directory_to_index, $index_location)
{
# Don't let the user place the index in the same folder being indexed, otherwise the directory
# cannot be re-indexed later, otherwise we will be indexing the index.
if ($directory_to_index == $index_location)
{
throw new Exception('Cannot place index in same folder being indexed!');
}
# delete the old index if one already exists.
if (file_exists($index_location))
{
deleteNonEmptyDir($index_location);
}
if (!mkdir($index_location))
{
throw new Exception('Failed to create index directory, check write permissions');
}
$files = scandir($directory_to_index);
foreach ($files as $filename)
{
$first_letter = $filename[0];
$placement_dir = $index_location . "/" . strtoupper($first_letter);
if (ctype_alpha($first_letter))
{
# create the placement directory if it doesn't exist already
mkdir($placement_dir);
$new_path = $placement_dir . "/" . $filename;
if (!is_link($new_path))
{
symlink($directory_to_index . '/' . $filename, $new_path);
}
}
}
}
/**
* Deletes a directory even if it is not already empty. This resolves the issue with
* trying to use unlink on a non-empty dir.
* @param String $dir - the path to the directory you wish to delete
* @return void - changes your filesystem
*/
function deleteNonEmptyDir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($dir . "/" . $object) == "dir")
{
deleteNonEmptyDir($dir . "/" . $object);
}
else
{
unlink($dir . "/" . $object);
}
}
}
reset($objects);
rmdir($dir);
}
}
create_file_index('/volume1/dir1', '/volume1/dir1/ByLetter');