I have a python script named utils (note without any .py extension). Where I have some utility functions. The path is also added in PATH variable.
#!/usr/bin/env python3
import click, sys
#main.command('echo', context_settings=dict(help_option_names=['-h', '--help']))
def echo_test():
click.echo("Hello World")
sys.exit(0)
It works fine. Now I can run from anywhere utils echo.
I am trying to make the script to use virtualenv instead of the global python. I have tried
#!/path/to/venv/bin python3
import click, sys
Then it throws me error permission denied
Permissions for utils file are -rwxr-xr-x
Any idea how could I use venv with script.
If your code is pasted correctly, your problem is that you are trying to execute a directory with your she-bang, not Python, because you have a space rather than a slash as a separator:
#!/path/to/venv/bin python3
rather than:
#!/path/to/venv/bin/python3
EDIT: By the way, is there a reason you want to change the code and not just activate the virtual environment, like it's supposed to be used?
If you want to do it, you can just:
$ source path/to/venv/bin/activate<.optional_extension>
You need the optional extension if you use a shell other than Bash (probably other Bourne-like shells too).
Try changing the file permissions via this command:
chmod 755
chmod -R 755 on the /usr/lib/python/site-packages/virtualenv
or even
chmod +x
Suggest you read the man page for chmod by using this command
man chmod
if you are not sure.
Related
I'm writing a python script which will be placed in a location. I want to execute it just like a command. for ex.
$ find_branch test
where find_branch is a script placed in anywhere in the system.
I would like to know how to achieve this. I can run it on the place where the script is present by chmod u+x on the script and removing the .py from the script
sudo nano /usr/bin/testpyscript
Then inside the script:
#!/usr/bin/python
print("I'm a python script")
Give it x permission:
sudo chmod +x /usr/bin/testpyscript
Now you can use it as a regular command:
bash-4.2$ testpyscript
I'm a python script
It doesn't have to be exactly at /usr/bin, any location that is inside your $PATH will do. Let's say you want it to be located at some folder inside your home directory, you could do something like this:
pwd
/home/brunorb
mkdir somedir
sudo mv /usr/bin/testpyscript somedir/
export PATH=$PATH:/home/brunorb/somedir/
testpyscript # from any folder in the system
I'm a python script
Make sure python has been added to your path and #!/usr/bin/python is located at the top of your script.
Note You could just try adding your script to your /usr/local/bin/ directory and give it the proper permissions.
sudo cp <your script> /usr/local/bin/
You have a number of options on how to achieve this.
Add the location where you put the script to your PATH environment variable, for example in your ~/.bashrc script:
export PATH="${PATH}:/folder/where/you/put/the/script"
Install the script to a location that is already on your path. It does not have to be a system folder like /usr/bin. Many default Bash setups will include ~/bin in your PATH.
Give the full path to your script on the command line:
/folder/where/you/put/the/script/find_branch test
Run the script through Python. This is very similar to option #2:
python /folder/where/you/put/the/script/find_branch test
Create an alias for the script in your environment. In bash you would do something like the following in your ~/.bashrc:
alias find_branch='/folder/where/you/put/the/script/find_branch'
OR
alias find_branch='python /folder/where/you/put/the/script/find_branch'
For options #1, #2, #3 and #5a to work properly, you should have a shebang with the version of python as the first line of the script. Any of the following will do, depending on how you have/want your environment set up:
#!/usr/bin/python
#!/usr/bin/python2
#!/usr/bin/python3
#!/usr/bin/env python
#!/usr/bin/env python2
#!/usr/bin/env python3
Finally, you do not have to remove the .py extension from the script if you do not want to. Many bash scripts have a .sh extension, for example, which does not prevent them from running as-is. You just have to include the extension in the name of the script when you run it.
So, once again, I make a nice python program which makes my life ever the more easier and saves a lot of time. Ofcourse, this involves a virtualenv, made with the mkvirtualenv function of virtualenvwrapper. The project has a requirements.txt file with a few required libraries (requests too :D) and the program won't run without these libraries.
I am trying to add a bin/run-app executable shell script which would be in my path (symlink actually). Now, inside this script, I need to switch to the virtualenv before I can run this program. So I put this in
#!/bin/bash
# cd into the project directory
workon "$(cat .venv)"
python main.py
A file .venv contains the virtualenv name. But when I run this script, I get workon: command not found error.
Of course, I have the virtualenvwrapper.sh sourced in my bashrc but it doesn't seem to be available in this shell script.
So, how can I access those virtualenvwrapper functions here? Or am I doing this the wrong way? How do you launch your python tools, each of which has its own virtualenv!?
Just source the virtualenvwrapper.sh script in your script to import the virtualenvwrapper's functions. You should then be able to use the workon function in your script.
And maybe better, you could create a shell script (you could name it venv-run.sh for example) to run any Python script into a given virtualenv, and place it in /usr/bin, /usr/local/bin, or any directory which is in your PATH.
Such a script could look like this:
#!/bin/sh
# if virtualenvwrapper.sh is in your PATH (i.e. installed with pip)
source `which virtualenvwrapper.sh`
#source /path/to/virtualenvwrapper.sh # if it's not in your PATH
workon $1
python $2
deactivate
And could be used simply like venv-run.sh my_virtualenv /path/to/script.py
I can't find the way to trigger the commands of virtualenvwrapper in shell. But this trick can help: assume your env. name is myenv, then put following lines at the beginning of scripts:
ENV=myenv
source $WORKON_HOME/$ENV/bin/activate
This is a super old thread and I had a similar issue. I started digging for a simpler solution out of curiousity.
gnome-terminal --working-directory='/home/exact/path/here' --tab --title="API" -- bash -ci "workon aaapi && python manage.py runserver 8001; exec bash;"
The --workingdirectory forces the tab to open there by default under the hood and the -ci forces it to work like an interactive interface, which gets around the issues with the venvwrapper not functioning as expected.
You can run as many of these in sequence. It will open tabs, give them an alias, and run the script you want.
Personally I dropped an alias into my bashrc to just do this when I type startdev in my terminal.
I like this because its easy, simple to replicate, flexible, and doesn't require any fiddling with variables and whatnot.
It's a known issue. As a workaround, you can make the content of the script a function and place it in either ~/.bashrc or ~/.profile
function run-app() {
workon "$(cat .venv)"
python main.py
}
If your Python script requires a particular virtualenv then put/install it in virtualenv's bin directory. If you need access to that script outside of the environment then you could make a symlink.
main.py from virtualenv's bin:
#!/path/to/virtualenv/bin/python
import yourmodule
if __name__=="__main__":
yourmodule.main()
Symlink in your PATH:
pymain -> /path/to/virtualenv/bin/main.py
In bin/run-app:
#!/bin/sh
# cd into the project directory
pymain arg1 arg2 ...
Apparently, I was doing this the wrong way. Instead of saving the virtualenv's name in the .venv file, I should be putting the virtualenv's directory path.
(cdvirtualenv && pwd) > .venv
and in the bin/run-app, I put
source "$(cat .venv)/bin/activate"
python main.py
And yay!
add these lines to your .bashrc or .bash_profile
export WORKON_HOME=~/Envs
source /usr/local/bin/virtualenvwrapper.sh
and reopen your terminal and try
You can also call the virtualenv's python executable directly. First find the path to the executable:
$ workon myenv
$ which python
/path/to/virtualenv/myenv/bin/python
Then call from your shell script:
#!/bin/bash
/path/to/virtualenv/myenv/bin/python myscript.py
noobiest question ever:
I'm trying to work with python via cygwin on my pc laptop - I have a file (foo.py) but python can't find it. The error it's giving me is:
$ chmod +x foo.py
chmod: cannot access `foo.py': No such file or directory
Is there a special location within the Cygwin folder that I need to save my foo.py?
Thanks!
AP
It's not python that can't find your file, it's the chmod command. C drive is mapped to /cygdrive/c in Cygwin, and D drive is mapped to /cygdrive/d and so on and so forth.
Are you in the same directory as the file when you are running chmod?
If your file is at C:\mycode\python\foo.py then you should either change to that directory first -
$ cd c:
$ cd mycode/python/
or as #Ahmed mentioned above, you could also run the command as
$ chmod +x /cygdrive/c/mycode/python/foo.py
But you only need chmod if your python script starts with
#!/bin/python
To execute such a file, you'd say
$ /cygdrive/c/mycode/python/foo.py
Or if you are in the same directory
./foo.py
If the first line of the python script isn't "#!/bin/python" then you can skip the chmod and just type
python /cygdrive/c/mycode/python/foo.py
You go right click on foo.py figure out its full path then do this:
chmod +x foos-full-directory/foo.py
And this should work for you and btw its not Python problem it's your pwd other than the foo.py working directory and you even didn't use python word in your command.
If I have a basic Python script, with it's hashbang and what-not in place, so that from the terminal on Linux I can run
/path/to/file/MyScript [args]
without executing through the interpreter or any file extensions, and it will execute the program.
So would I install this script so that I can type simply
MyScript [args]
anywhere in the system and it will run? Can this be implemented for all users on the system, or must it be redone for each one? Do I simply place the script in a specific directory, or are other things necessary?
The best place to put things like this is /usr/local/bin.
This is the normal place to put custom installed binaries, and should be early in your PATH.
Simply copy the script there (probably using sudo), and it should work for any user.
Walkthrough of making a python script available anywhere:
Make a python script:
cd /home/el/bin
touch stuff.py
chmod +x stuff.py
Find out where your python is:
which python
/usr/bin/python
Put this code in there:
#!/usr/bin/python
print "hi"
Run in it the same directory:
python stuff.py
Go up a directory and it's not available:
cd ..
stuff.py
-bash: stuff.py: command not found
Not found! It's as we expect, add the file path of the python file to the $PATH
vi ~/.bashrc
Add the file:
export PATH=$PATH:/home/el/bin
Save it out, re apply the .bashrc, and retry
source ~/.bashrc
Try again:
cd /home/el
stuff.py
Prints:
hi
The trick is that the bash shell knows the language of the file via the shebang.
you can also use setuptools (https://pypi.org/project/setuptools/)
your script will be:
def hi():
print("hi")
(suppose the file name is hello.py)
also add __init__.py file next to your script (with nothing in it).
add setup.py script, with the content:
#!/usr/bin/env python3
import setuptools
install_requires = [
'WHATEVER PACKAGES YOU NEED GOES HERE'
]
setuptools.setup(
name="some_utils",
version="1.1",
packages=setuptools.find_packages(),
install_requires=install_requires,
entry_points={
'console_scripts': [
'cool_script = hello:hi',
],
},
include_package_data=True,
)
you can now run python setup.py develop in this folder
then from anywhere, run cool_script and your script will run.
Just create ~/bin and put export PATH=$PATH:$HOME/bin in your bashrc/profile. Don't mess with the system, it will bite you back, trust me.
Few more things (relevant to the question but not part of the answer):
The other way export PATH=$HOME/bin:$PATH is NOT safe, for bash will will look into your ~/bin folder for executables, and if their name matches with other executables in your original $PATH you will be surprised by unexpected/non working command execution.
Don't forget to chmod+x when you save your script in ~/bin.
Be aware of what you are putting in your ~/bin folder, if you are just testing something or working on unfinished script, its always better to use ./$SCRIPT_NAME from your CWD to execute the script than putting it under ~/bin.
The quick answer is to symlink your script to any directory included in your system $PATH.
The long answer is described below with a walk through example, (this is what I normally do):
a) Create the script e.g. $HOME/Desktop/myscript.py:
#!/usr/bin/python
print("Hello Pythonista!")
b) Change the permission of the script file to make it executable:
$ chmod +x myscript.py
c) Add a customized directory to the $PATH (see why in the notes below) to use it for the user's scripts:
$ export PATH="$PATH:$HOME/bin"
d) Create a symbolic link to the script as follows:
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
Notice that hello (can be anything) is the name of the command that you will use to invoke your script.
Note:
i) The reason to use $HOME/bin instead of the /usr/local/bin is to separate the local scripts from those of other users (if you wish to) and other installed stuff.
ii) To create a symlink you should use the complete correct path, i.e.
$HOME/bin GOOD ~/bin NO GOOD!
Here is a complete example:
$ pwd
~/Desktop
$ cat > myscript.py << EOF
> #!/usr/bin/python
> print("Hello Pythonista!")
> EOF
$ export PATH="$PATH:$HOME/bin"
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
$ chmod +x myscript.py
$ hello
Hello Pythonista!
Just create symbolic link to your script in /usr/local/bin/:
sudo ln -s /path/to/your/script.py /usr/local/bin/script
Putting the script somewhere in the PATH (like /usr/local/bin) is a good solution, but this forces all the users of your system to use/see your script.
Adding an alias in /etc/profile could be a way to do what you want allowing the users of your system to undo this using the unalias command. The line to be added would be:
alias MyScript=/path/to/file/MyScript
i find a simple alias in my ~/.bash_profile or ~/.zshrc is the easiest:
alias myscript="python path/to/my/script.py"
Type echo $PATH in a shell. Those are the directories searched when you type command, so put it in one of those.
Edit: Apparently don't use /usr/bin, use /usr/local/bin
Acording to FHS, the /usr/local/bin/ is the good place for custom scripts.
I prefer to make them 755 root:root, after copying them there.
When I want to run my python applications from commandline (under ubuntu) I have to be in the directory where is the source code app.py and run the application with command
python app.py
How can I make it (how is it conventionally done) to run the application from arbitrary directory with the command: app ? Similarly as you type ls, mkdir and other commands?
thank you
Add a shebang line at the beginning of your file:
#!/usr/bin/env python
Make your file executable by calling
chmod +x app.py
in the shell.
Move it to some location included in the PATH environment variable and rename it to app. Alternatively, add the path of the directory containing app to the PATH environment variable by adding the line
export PATH=$PATH:/path/to/app
to your .bash_profile.
Add the directory that the script is in to your path, make it executable, and add a proper shebang line.
In your .bashrc:
PATH=$PATH:/dir/to/the/script
Executable:
chmod +x myscript.py
At the top of the script, add the shebang line:
#!/usr/bin/env python
Then, from anywhere, you can just do:
myscript.py
(Note that you don't need a .py suffix, it could be called anything, e.g. app if you have a proper shebang line).
Add a shebang: as the top line of the file: #!/usr/bin/python or #!/usr/bin/python3 (you can use the python -B to prevent generation of .pyc files, which is why I don't use /usr/bin/env)
Make it executable: You will need to do chmod +x app.py
(optional) Add directory to path, so can call it anywhere: Add a directory with your executable to your $PATH environment variable. How you do so depends on your shell, but is either export PATH=$PATH:/home/you/some/path/to/myscripts (e.g. Linux distros which use bash) or setenv PATH $PATH:/home/you/some/path/to/myscripts (e.g. tcsh like in Mac OS X). You will want to put this, for example, in your .bashrc or whatever startup script you have, or else you will have to repeat this step every time you log in.
app.py will need to be in the myscripts (or whatever you name it) folder. You don't even need to call it app.py, but you can just rename it app.
If you wish to skip step #3, you can still do ./app to run it if you are in the same directory.
Probably you want to symlink to your file location instead of adding another location to the path
chmod +x app.py
ln ~app.py /opt/local/bin/app
...assuming that /opt/local/bin is already in your path,.
Also, do not forget to add the shebang line to the first line of your script:
#!/usr/bin/env python
A solution some what different from the ones mentioned here: Use an alias.
alias app='python /path/to/app.py'
Add the above line to your ~/.bashrc or ~/.bash_login file (or preferably to ~/.bash_aliases if you are on Ubuntu). Then you can simply use your script as a command line tool with app.
No need to add a shebang (thereby modifying your existing Python script), no need to make the script executable and no need to change your PATH.
I'm pretty sure you have to make the script executable via chmod +x and put it in the PATH variable of your system.