Frage

I have a Python script which I then ran through pyinstaller2.0 to generate its binary.

python pyinstaller -F /path/to/python/script

While running the binary, it uses the /tmp folder by default to save it's temporary files and run the installer. This works fine on normal servers and VPSes. However, when an install is attempted on a server where /tmp is disabled (/tmp noexec), the installation fails.

My questions are as follows:

  • How would I enable another temporary location when the binary is run? does pyinstaller have such an option?
  • If I write the code to create a temp location and export it to the PATH inside the python script, won't it anyway try to use default /tmp to run the python binary anyway?
  • Another method I thought of was to write a shell script in bash which creates a temp location, exports its PATH, then calls the python binary and after it has run , remove the location of temp from PATH, and delete the temp folder - but this seems like a roundabout way to get it done. Is there a better solution?
War es hilfreich?

Lösung 2

The solution as suggested by @devnull was indeed to make changes in pyinstaller's script. The script had the temporary location hardcoded so I made changes there. So here are the steps followed:

  • Under the pyinstaller folder, look for the launch.c file under /path/to/pyinstaller/sources/common
  • Look for a function called int getTempPath(char *buff)
  • Under it, delete references to the static const char *envname[] (which are, it's declaration and one for loop within the same function)
  • Change the values for static const char *dirname[] to to the values which you want.

The function thus, looks like so:

int getTempPath(char *buff)
{
        static const char *dirname[] = {
                "/usr/local/src/temp", "/usr/local/src", "/usr/src", 0
        };
        int i;
        char *p;
        for ( i=0; dirname[i]; i++ ) {
                strcpy(buff, dirname[i]);
                if (testTempPath(buff))
                        return 1;
        }
    return 0;
}

Recompile the pyinstaller sources using the following command:

python ./waf configure --no-lsb build install

To run this, first install python-devel packages (yum install python-devel -y) else it throws and error that Python.h isn't found

Now when we run the python script through pyinstaller, the new temp local is used. Thanks to @devnull for pointing me in the right direction.

Andere Tipps

Since PyInstaller V3.3 (2017-09-21) you can use the --runtime-tmpdir argument to change the default extracting path, i.e.:

--runtime-tmpdir PATH

Where to extract libraries and support files in onefile-mode. If this option is given, the bootloader will ignore any temp-folder location defined by the run-time OS. The _MEIxxxxxx-folder will be created here. Please use this option only if you know what you are doing.

@devnull was on the right track. The missing piece is that those environment variables are resolved when the installer binary is run on the target machine, not when the installer is compiled on the development machine.

A two line shell script that changes the TMPDIR environment variable (or %TEMP% in Windows) to somewhere you can run code from and then calls the binary you compiled should get the job done.

Incidentally this method has the advantage that it also works if you get a pyinstaller generated binary from someone else and don't have access to the source code.

As noted by @Darkerlvy in a comment there is now a command line option --runtime-tmpdir PATH which you can pass to pyinstaller. No need to modify the source or set an env variable. It was introduced in pyinstaller 3.3

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top