Tente usar um caminho absoluto. O código unlink("testFile");
procura por um arquivo no diretório de trabalho atual. O pwd muda de acordo com o diretório de trabalho atual. Então use unlink("/path/to/testFile");
Eu tenho um script PHP em execução que faz links simbólicos.
Para confirmar qual usuário é:
file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
echo "running as user '" . $user . "'";
var_dump( exec('whoami'));
funcionando assim ...
$ php script.php
executa corretamente todos os links simbólicos são criados e a saída é:
running as user '999'string(5) "admin"
Executando um script de shell:
#!/bin/sh
php /path/to/script.php
fornece a seguinte saída e não funciona:
PHP Warning: symlink(): Permission denied in /path/to/script.php on line 8 running as user '999'string(5) "admin"
Não sei qual é a diferença entre os dois, pois os usuários que estão executando são idênticos.
Alguma sugestão sobre como fazer com que ambos tenham as permissões corretas para o symlinking?
cat /proc/version
dá:
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
Essa é a única saída que posso gerar para qualquer tipo de informação de lançamento.
Todo o código:
$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);
}
}
fornece a mesma saída para os dois métodos de dump.
Tente usar um caminho absoluto. O código unlink("testFile");
procura por um arquivo no diretório de trabalho atual. O pwd muda de acordo com o diretório de trabalho atual. Então use unlink("/path/to/testFile");
Eu peguei o código que você postou, achei que era o começo de uma função útil, ajustei-a e não consegui fazer com que ela falhasse (provavelmente porque meu usuário tem acesso de gravação aos dois caminhos). Certifiquei-me de adicionar muitos cheques para que você saiba se algo está errado. Deixe-me saber se você ainda tem o mesmo problema. Lembre-se de que, se você executar o script por meio da CLI, o script terá as permissões necessárias, mas, se executado por meio de um servidor da Web, terá as permissões do usuário do servidor da Web (por exemplo, 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');
A função PHP fileowner
retorna um numérico uid e não um nome de usuário. O uid 999 provavelmente corresponde ao seu usuário admin
; você pode verificar isso com o comando id
:
id admin
A saída deve começar com o uid dessa conta.
Tags permissions php symlink