Excute script only from another file

H

Himanshu Garg

I want that a script should only be executed when it is called from another script and should not be directly executable through linux command line.

Like, I have two scripts "scrip1.py" and "script2.py" and there is a line in "script1.py" to call "script2.py" as subprocess.call(["python", "script2.py"]).

Then this is should call script2 but I should not be able to directly call script2 as $python script2.py
 
M

Michael Torrie

I want that a script should only be executed when it is called from
another script and should not be directly executable through linux
command line.

Like, I have two scripts "scrip1.py" and "script2.py" and there is a
line in "script1.py" to call "script2.py" as
subprocess.call(["python", "script2.py"]).

Then this is should call script2 but I should not be able to directly
call script2 as $python script2.py

I'm not totally sure what you mean, but if you want to prevent the
script from doing anything when run from the command line but have it do
something when imported as a module then just put this at the beginning:

if __name__ == "__main__":
import sys
sys.exit(0)
 
C

Chris Angelico

I want that a script should only be executed when it is called from another script and should not be directly executable through linux command line.

Like, I have two scripts "scrip1.py" and "script2.py" and there is a line in "script1.py" to call "script2.py" as subprocess.call(["python", "script2.py"]).

Then this is should call script2 but I should not be able to directly call script2 as $python script2.py

Easy! Just have your subprocess.call pass a special argument, which
you then look for in script2:

subprocess.call(["python", "script2.py","confirm"])

# script2.py
import sys
if "confirm" not in sys.argv:
print("This script should not be run directly.")
sys.exit(1)

# rest of script2.py follows

ChrisA
 
D

Dave Angel

Like, I have two scripts "scrip1.py" and "script2.py" and there is
a line in "script1.py" to call "script2.py" as
subprocess.call(["python", "script2.py"]).
Then this is should call script2 but I should not be able to
directly call script2 as $python script2.py

Are you really trying to protect against yourself accidentally
invoking it or someone maliciously doing it?

I would probably give scrpt2 an obnoxious name like
htrerttcdrrthyyh.py or put it in an obscure directory. But if you
explain the rationale we might come up with something better.

How about naming it dontrunme.py ?
 
P

Peter Otten

Himanshu said:
I want that a script should only be executed when it is called from
another script and should not be directly executable through linux command
line.

Like, I have two scripts "scrip1.py" and "script2.py" and there is a line
in "script1.py" to call "script2.py" as subprocess.call(["python",
"script2.py"]).

Then this is should call script2 but I should not be able to directly call
script2 as $python script2.py

Put the toplevel code into a function, i. e. change

#script2.py old
print "hello from script2"

to

# script2.py new

def f(): # you should pick a descriptive name instead of f
print "hello from script2"

and then import it from script1 and invoke the function:

# script1.py old
#...
subprocess.call("python", "script2.py")
#...

# script1.py new
import script1
#...
script.f()
#...
 
H

Himanshu Garg

I was also thinking to add a sys argument when invoking script and check it.

My motive is "I will give scripts to somebody else and he should not run the script directly without running the parent script".
 
D

Dave Angel

My motive is "I will give scripts to somebody else and he should
not run the script directly without running the parent script".

Perhaps it should be a module, not a script. Have it protect itself
with the usual if __name__ == "__main__"

And of course it gets executed by an import and a call.
 
R

Rick Johnson

My motive is "I will give scripts to somebody else and he
should not run the script directly without running the
parent script".

The only sure fire method to prevent a file containing
Python code from executing on a machine with Python
installed is to use an extension that the system will not
associate with Python.

ScriptFolder/
script.py
mod_1.ignore
mod_2.ignore
...

Of course, any other Python module that needs to leverage
the API contained within the "aliased mod files" will need
to do so *manually*:

1. Read the file from disc
2. Evaluate the file contents and make callable
3. Close the file

Sounds like your distributing a Python application and need
a simplistic method by which "non-techies" can run the code,
but as we all know:

"fools are too cleaver!"

Of course a smarty pants could could change the extension to
"py[w]", but that would be violating your interface. :)

Another choice would be to use a package.

ScriptPackageFolder/
__init__.py
__script.py
mod_1.py
mod_2.py
...

But nothing could stop them from accessing the contents of
the package directory.

A third alternative would be to install the support modules
in a place that the user would be unlikely to look and then
place a mainscript somewhere that is easily accessible. But
even this method will not prevent the running of py scripts.

Sounds like my first offering is the best. At least with
that method they would be forced into an explicit act of
renaming the file before they violate your interface.
 
C

Chris Angelico

The only sure fire method to prevent a file containing
Python code from executing on a machine with Python
installed is to use an extension that the system will not
associate with Python.

ScriptFolder/
script.py
mod_1.ignore
mod_2.ignore
...

Windows:
C:\Documents and Settings\M>copy con test.ignore
print("Hello, world!")
^Z
1 file(s) copied.

C:\Documents and Settings\M>python test.ignore
Hello, world!

Linux:
gideon@gideon:~$ cat >test.ignore
print("Hello, world!")
gideon@gideon:~$ python test.ignore
Hello, world!

Totally sure-fire. Absolutely prevents any execution until it's
renamed. By the way, what does "associate" mean, and what does it have
to do with file names?

gideon@gideon:~$ cat >test.ignore
#!/usr/bin/python
print("Hello, world!")
gideon@gideon:~$ chmod +x test.ignore
gideon@gideon:~$ ./test.ignore
Hello, world!

ChrisA
 
S

Steven D'Aprano

The only sure fire method to prevent a file containing Python code from
executing on a machine with Python installed is to
[snip bad advice]

.... is to delete Python from the system, or the Python code. Or both.

If Python can read a file, it can exec it.

I suppose you could use file permissions and ACLs to prevent Python from
reading the file, rather than delete it, but given the possibility of
privilege-escalation security vulnerabilities, even that's not sure-fire.
 
R

Rick Johnson

Totally sure-fire. Absolutely prevents any execution until it's
renamed.

Doh! It seems Python's quite the sneaky little snake!
By the way, what does "associate" mean, and what does it have
to do with file names?

Hmm, I did not see his "command line snip-it" and assumed his users where not "command line savvy", therefor they would be running the script via a mouse click -- still probably not "sure fire" advice either.

Okay, Rick was wrong once. get over it! :p"
 
D

Dennis Lee Bieber

Totally sure-fire. Absolutely prevents any execution until it's
renamed. By the way, what does "associate" mean, and what does it have
to do with file names?
Windows-speak...

Where UNIX/Linux relies upon the first line of a script to identify
what executable is used to process it (the #! line), Windows uses a linked
pair of registry entries


C:\Users\Wulfraed\Documents>assoc .py
..py=Python.File

C:\Users\Wulfraed\Documents>ftype python.file
python.file="C:\PYTHON~2\Python27\python.exe" "%1" %*

C:\Users\Wulfraed\Documents>


"ftype" takes a type label and defines the command line used to execute
that file type (or otherwise open the file... ).

"assoc" takes a file extension and "associates" it with the type label
-- allows multiple extensions to be linked to one command line

..py=Python.File
..pyc=Python.CompiledFile
..pyo=Python.CompiledFile
..pys=pysFile
..pyw=Python.NoConFile


Python.CompiledFile="C:\PYTHON~2\Python27\python.exe" "%1" %*
Python.File="C:\PYTHON~2\Python27\python.exe" "%1" %*
Python.NoConFile="C:\PYTHON~2\Python27\pythonw.exe" "%1" %*

(No idea where .pys came from -- it has no defined executor)

These are how one can do things like

C:\Users\Wulfraed\Documents>scite t.py

C:\Users\Wulfraed\Documents>python t.py
Goodbye

C:\Users\Wulfraed\Documents>t.py
Goodbye

C:\Users\Wulfraed\Documents>t
Goodbye

There's another environment variable that defines what order to search
extensions when not provided (as in the last sample above), as one may have
a t.py, t.bat, t.doc, etc.

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.py;.pyw

Hmmm, think I need to edit that... shove the .py* behind .bat -- I don't
use the others so why have the system try to find them first. I'd add
powershell but its designed for security and pretty much needs to be
manually invoked.
 
C

Chris Angelico

Windows-speak...

Where UNIX/Linux relies upon the first line of a script to identify
what executable is used to process it (the #! line), Windows uses a linked
pair of registry entries

Yeah. It's usually a GUI feature, not a command-line one, and it
certainly has nothing to do with preventing execution - it is strictly
a convenience. In the OS/2 WorkPlace Shell, you can associate files
with programs by either a filename pattern (which doesn't have to be
star-dot-something - I've always had an association "Makefile.*"),
file type (not MIME type - this system predates that - but a category
that files can be added to), object class (when a file is created, it
can be a subclass of WPFile, like DeScribeDocument), or manually on an
individual file, which is then stored as an extended attribute on that
file. But it's still nothing more than a shortcut - it lets you put a
program into the "Open ->" menu, and (optionally) choose one program
from said menu to be the default, which is run when you double-click
on the file's icon (or call the associated method on the file's object
- everything in the WPS is an object, and naturally any program can
send any object any method). Deleting or breaking an association
doesn't stop you dragging the icon onto the program - which is
sometimes necessary in situations where information isn't properly
carried through. It certainly does not stop Python from executing a
script.

My point was that Rick had made the assumption that the GUI was
*everything* and that users were able to do nothing beyond
double-clicking on icons - and that he did not mention this
assumption, suggesting he was unaware that he had made it.

ChrisA
 
R

Rick Johnson

My point was that Rick had made the assumption that the GUI was
*everything* and that users were able to do nothing beyond
double-clicking on icons

For some people the GUI *is* everything.

Most people are unaware that life *even* exists beyond the
"point and click". Heck, If you opened a command prompt in
front of them, they'd run and hide in a closet for the next
three hours consumed with fear. They'd probably convince
themselves that "cryptic commands" in a "black window" could
be nothing less than sorcery -- and that's usually when the
pitchforks come out.

Chris, it's obvious you need to climb down from the tower
and mingle with the peasants a bit -- don't worry, we'll
delouse you when you get back ;-)
 
C

Chris Angelico

Most people are unaware that life *even* exists beyond the
"point and click". Heck, If you opened a command prompt in
front of them, they'd run and hide in a closet for the next
three hours consumed with fear. They'd probably convince
themselves that "cryptic commands" in a "black window" could
be nothing less than sorcery -- and that's usually when the
pitchforks come out.

[citation needed]
Chris, it's obvious you need to climb down from the tower
and mingle with the peasants a bit -- don't worry, we'll
delouse you when you get back ;-)

My mother used to be the sort who didn't even use computers if she
didn't have to. Now, she happily uses Debian Wheezy on her laptop, and
if I ask her to pull up a terminal and type something, she knows how
to do that.

Stephanie Gibson is a soprano from the operatic society I work with.
She uses a Mac, probably the strongest "use a GUI not a terminal"
system in popular use today. And when she had networking issues, I was
able to show her how to pull up a terminal, and she handled it just
fine - to the point of grokking how to skim the output of ifconfig for
the pertinent bits, without even being instructed.

I have worked with innumerable people. Never yet have I found a single
one who ran away in fear, pulled out pitchforks, or anything of the
sort. Yes, there are plenty of people who don't like to memorize
commands (my former boss thought that all command-line UIs are by
definition cryptic, I think because he came across a few
poorly-documented ones), but very few who can't accept dictation - and
much more easily than mouse clicks can be dictated.

ChrisA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top