0

I am creating a small extension to Nautilus using Python. I've seen some installation instructions around the web like:

curl 'https://example.com/some-program/install.sh' | bash

Since I am writing the extension on Python I made my "installer" run on the '__main__' like:

curl 'https://example.org/my-extension/script.py' | python

The issue on hand is that I would like that the script copy itself to the appropriated location WITHOUT re-downloading the script. How could I write the Python script in a way to save itself without downloading itself again?

I am accepting any shell trickery or python wizardry that doesn't change the curl 'https://example.org/my-extension/script.py' | python too much.

  • 1
    No matter how you slice it, there will be some duplication somewhere. The kind of thing you're asking about, though, is called a [quine](https://en.wikipedia.org/wiki/Quine_(computing)). Regardless I don't think you can actually pipe input into python and have it execute. Something like `curl 'https://example.org/my-extension/script.py' | python` doesn't actually run the downloaded code. – Ouroborus Jun 05 '23 at 23:05
  • @Ouroborus It is okay to have some duplication, as far the script doesn't download itself from the web again. My question is not about a Quine. I don't want to print itself. I want to access the python interpreter and get the source code being interpreted to write it down on a file. Piping the curl to python works. Try it out: `https://gist.githubusercontent.com/theoamonteiro/2e03ed86fb3c16865e9270305ac072f6/raw/ce087c21423bdb9818c4880691d03619132899b8/script.py | python` – theoamonteiro Jun 06 '23 at 06:29
  • Does this answer your question? [How to get the current script's code in Python?](https://stackoverflow.com/questions/34491808/how-to-get-the-current-scripts-code-in-python) – Ouroborus Jun 06 '23 at 15:58
  • See the comments in that question's answer. The thing preventing you from doing it is the pipe. – Ouroborus Jun 06 '23 at 15:59
  • @Ouroborus I tried `print(inspect.getsource(sys.modules[__name__]))` and `print(inspect.getsource(inspect.getmodule(inspect.currentframe())))`. Both produce a `OSError`. I also tried `python <(curl https://example.org/my-extension/script.py)` with both print options, but the same `OSError` is raised. The pipe is not a requirement per se, but it must be an "one-liner" command and it SHOULD NOT download the script a second time. – theoamonteiro Jun 06 '23 at 20:07
  • Oh, if you just need a one-liner and you don't really care what the technique is, then it'd be `wget 'https://example.org/my-extension/script.py' ; python script.py`. The python script can then pick up the file from the current directory. – Ouroborus Jun 07 '23 at 01:05

1 Answers1

0

You might exploit -c command switch for that purpose, using wget following way, let say install.py is as follows

print("Install")
print("Installing...")
print("Finished")

available at www.example.com, then

python -c "$(wget -q -O - http://www.example.com/install.py)"

gives output

Install
Installing...
Finished

Explanation: use output of wget command writing to standard output (-O -) without informing about downloading (-q) as argument to -c option. Note: I used wget as I am well versed with it, if you are able to summon curl ninja you might be able to get similar effect using curl.

Daweo
  • 31,313
  • 3
  • 12
  • 25