I have a python script fetchcreative.py which typically fetches some data from db . The script has execute permission . When i run the script using
./fetchcreative.py rtb:3778:4019617065
it fails with ImportError: No module named psycopg2.
But when i run using
python fetchcreative.py rtb:3778:4019617065
it works fine. Just want to understand , what is going on here ? Please point to corresponding reference where i can learn more about it .
./fetchcreative.py will use the shebang (#!) magic at the beginning of the file to determine which python to run.
Usually it is best to have:
#!/usr/bin/env python
at the beginning of a script.py to get python from the environment (i.e. from $PATH) which should match (though aliases and other actions could make it different):
$ python script.py
However, if the #! is hard-coded to a specific python it may not match python on the command line.
Related
I have a MacBook air and have tried opening Python in terminal but when I open it, it opens Python interactive mode. Does anyone know how to open Python script mode please.
I’ve tried typing in things such as Python or Python 3 like safari suggests but that didn’t work.
There is no 'script mode'. You can create a Python script using TextEdit or another editor, save it as myfile.py, and then run it with python myfile.py.
for running what you are calling 'script version' of python you should choose a python file to run and make sure is written in the same or in a compatible version to the python you are running it with (python2, python3)
For running an example script:
python main.py
You need to be in the directory containing the file so make sure you are there before running the command. Using python runs the first version of python you installed, so if you want to use an other you should use:
python2 main.py
python3 main.py
etc
Assuming you've stored your script in a file named itworks.py, the simplest thing is to type the command python3 itworks.py in a terminal window after you've moved to the directory containing the script. Alternatively, you can type python3 followed by a space, then locate your python script in the Finder and drag and drop it into the terminal. This will expand to the full path to the file, allowing you to run a script located elsewhere than your current directory. Don't forget to press return...
In older versions of MacOS you could say python, but that uses python 2 which is no longer supported so you should go with python3 for any new development. (With MacOS Ventura, python 2 seems to have been removed.)
If you have multiple versions of python, you can use the command which -a python3 (or python) to see all versions on your PATH, and the order in which they will be found. PATH works on a first-come-first-served basis, but you can override by using the fully qualified path name to an alternative python.
Yet another solution, for when you want a more permanent script you will use many times in the future, is to use a "shebang" line as the first line of your script. For example, I wrote the following tiny demo:
#!/usr/bin/env python3
print('It works!')
The first line says to parse this script with the first python3 interpreter found in your current environment's PATH. You could replace that with an explicit path such as #!/opt/homebrew/bin/python3. Now make the script executable: chmod a+x itworks.py. You can now run the script from the current directory by typing ./itworks.py. (The leading ./ tells your shell you know it's in the current directory, and is intended as protection against trojan horse scripts.) If you want to be able to use the now-executable script from anywhere, add it to a directory on your path such as /usr/local/bin, and you'll be able to run it by just typing itworks.py.
I'm not able to understand how
google-cloud-sdk/bin/dev_appserver.py helloworld runs automatically.
I mean to ask that it should run under python command as it is a python file.
is there something added to path??
Yes, dev_appserver.py is an executable python script. If you launch it by itself it will be executed under whichever python is the default one in your environment, see its 1st line:
#!/usr/bin/env python
If you want you can also execute it with a specific python version (it has to be a python 2.7 one, though, the only one supported by GAE standard environment):
/specific_path/python /path_to/google-cloud-sdk/bin/dev_appserver.py helloworld
Is it possible to use a "more complex" shell than just a single command shell? We have written a python shell that is a command loop, and it works fine in /etc/passwd like this:
user:x:1000:1000::/home/user:/usr/bin/ourshell.py
Of course the Python file has the shebang line for /usr/bin/python in it. However, we'd like to compile the Python shell into a .pyc file to save a bit of time on execution in login. So, after compiling, I've been trying to "quote" the shell line in /etc/passwd as "python ourshell.pyc", and I even tried making the shell a bash script which simply executes that same command (with the initial arguments).
Of course none of this has worked. When we SSH in, there is always some kind of error. Is there any special trick to what I am trying to do?
CPython's .pyc files are not text, and do not allow use of a shebang line. The traditional method is to have your called script be tiny; it would simply import a module with the rest of the program, which can then be precompiled. For instance, here is the main script of xonsh:
#!/usr/bin/env python3 -u
from xonsh.main import main
main()
This script takes negligible time to compile. It is also possible to run installed modules using -m, but that takes module names, not filenames, so is not suitable for a shebang script.
I suggest to code a small C wrapper program running your python shell.
(notice that execve(2) forbids nested shebang interpreters; I don't know if that applies for your case)
Look into your log files, probably /var/log/messages and /var/log/auth.log
You may also need to explicitly add (the compiled C executable for the wrapper) to /etc/shells; see shells(5)
Look also into scsh.
Your sshd daemon is probably using Linux Plugin Authentification Modules. So read more about PAM.
Create a file /usr/bin/shell_wrapper that contains this one line:
#!/usr/bin/python /usr/bin/ourshell.pyc
The compiled bytecode ourshell.pyc has to live in /usr/bin, or else change the path accordingly. The python path should go to the same version that compiled the bytecode.
Then make sure to have your /etc/passwd use /usr/bin/shell_wrapper for the shell executable:
user:x:1000:1000::/home/user:/usr/bin/shell_wrapper
I have a python program that I usually run as a part of a package:
python -m mymod.client
in order to deal with relative imports inside "mymod/client.py." How do I run this with pdb - the python debugger. The following does not work:
python -m pdb mymod.client
It yields the error:
Error: mymod.client does not exist
EDIT #1 (to address possible duplicity of question)
My question isn't really about running two modules simultaneously python, rather it is about how to use pdb on a python script that has relative imports inside it and which one usually deals with by running the script with "python -m."
Restated, my question could then be, how do I use pdb on such a script while not having to change the script itself just to have it run with pdb (ie: preserving the relative imports inside the script as much as possible). Shouldn't this be possible, or am I forced to refactor in some way if I want to use pdb? If so what would be the minimal changes to the structure of the script that I'd have to introduce to allow me to leverage pdb.
In summary, I don't care how I run the script, just so long as I can get it working with pdb without changing it's internal structure (relative imports, etc) too much.
I think I have a solution.
Run it like this:
python -m pdb path/mymod/client.py arg1 arg2
that will run it as a script, but will not treat it as a package.
At the top of client.py, the first line should be:
import mymod
That will get the package itself loaded.
I am still playing with this, but it seems to work so far.
This is not possible. Though unstated in documentation, Python will not parse two modules via the -m command line option.
This question has probably been asked to death, but I can't seem to find the answer.
I can run python 3 script like this:
python3 my.py
However, suppose I make it executable and run it on its own. Then it typically executes under python 2, but I want it under python 3. Is this possible?
chmod u+x my.py
./my.py #executes under python 2.
Can I add something to the first line of the script? Or can I change global system default? (I'm on OS X).
Also, is it safe to change global default, will any of my applications stop working?
Almost all *nix variants support the following:
#!/usr/bin/env python3
So adding it as the first line will find Python 3 assuming the path where python resides is including in the $PATH
I think that if you write
#!/usr/local/bin/python3
as the first line of the file, it will be executed b python 3.
Note that you must execute it as:
./my.py
if you do
python my.py
I have no idea what might happen. If your default python version is 2.7, it will probably be executed by that version.