I think the thing to do is have your php
/python
return the data directly instead of apache
. Your code can do the same thing that apache
does. In my experience this is much better than opening up another directory and/or using sudo
, or changing file permissions for apache
, etc.
If the program produces the large file faster than the internet connection, then you can stream the data directly from your program, which eliminates the extra data file and the code to manage it and the mechanisms to remember it.
This answer on Stack Overflow shows how the code works in php
. https://stackoverflow.com/a/4357904/5484716.
For programs that will be called this way, eliminate all stderr
stream output and make sure the return code from your python process accurately reflects the success or failure of the process.
The examples below show the popen()
calls you would use in the above example scenario from stackoverflow. I've prepended exec 2>/dev/null;
to the shell command. This ensures that no output goes to stdandard error, even from the shell itself, because having data coming on both stderr
and stdout
can be a source of deadlocks with popen()
.
If you want to download the disk file to your user:
$fp = popen('exec 2>/dev/null; sudo -u theuser cat yourfile.zip', 'r');
If you want to download the data from the active process:
$fp = popen('exec 2>/dev/null; sudo yourpythonscript arg argN', 'r');
These command lines are shell commands and need to be quoted appropriately for shell meta characters.
In the second method, the server would begin sending the data immediately. When the user successfully submits the form, they immediately see a "save as" dialog from their browser. As soon as the user selects the output file, your php
script transmits the data directly across the wire and into the remote file.
The python
script should print only the zip data on standard output, and return an exit code that accurately represents the success or failure of the zip process. In python
the script should write the output on sys.stdout
, for example zf = ZipFile(sys.stdout, ...
.
It is critical to call pclose()
and check the return value, because that will be the only way you know if the zip succeeded or not. If pclose()
returns anything other than 0, something is wrong.
How the file is handled by the client depends on the settings of these response headers
and others: content-type:
, content-encoding:
, and content-disposition:
See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html, look at the response-header
and the entity-header
information.
Best Answer
..
is a hard link to the parent directory which is created as part of the directory entry.If you issue
ls -ail
in each of these directories, you should see that the following entries all have the sameinode
(first field) and hard link count (third field):..
when executingls -ail
ininner
.
when executingls -ail
inmiddle
middle
when executingls -ail
inouter
There is one
..
entry ininner
. If your current working directory isouter
, you should see the same results (a directory listing ofmiddle
) fromls -al inner/..
ls -al middle/inner/..
The only situation in which "accessing"
..
through the symbolic link should provide different behavior is if youcd
intoinner
using the symbolic link, so that your logical working directory (pwd -L
) differs from your physical working directory (pwd -P
). In this case,cd ..
will take you back toouter
not because there is a different..
entry, but because your shell is keeping track of your logical working directory and popping you out one level, rather than referencing the actual..
entry ininner
.This is a convenience provided by, for example
bash
as part of the built-incd
command. You can override this by asking it to change to the actual..
entry withwhere
-P
instructscd
(as withpwd
above) to use the physical path.