I just can't figure out why this is happening...
in my fabric file I have this...
def func():
local("source ../venv/bin/activate")
It is returning 127 on the source command and I am not sure why, when i try to run source in my terminal manually it works. When I try a different command in fabric, like...
local("echo 'foo'")
it also works. Why would source be causing problems? I can't see any reason why this would be happening.
source is unknown by sh. If you want to run a command in the context of a virtual environment, use Fabric's context managers and run the activate binary without source. I've adapted from this answer.
from __future__ import with_statement
from fabric.api import *
from contextlib import contextmanager as _contextmanager
env.activate = '. ./.env/bin/activate'
#_contextmanager
def virtualenv():
with prefix(env.activate):
yield
def deploy():
with virtualenv():
local('echo hello world!')
Related
Looking to use a include a redis server for storing application specific data with my pyinstaller bundled application.
Before getting into it hands-on, need some guidance.
Are these the steps to follow for it?
(1) Bundle redis-server executable. And run it as a standalone application via some script in my bundled package.
(2) Use redis client packages in python to connect to the redis-server
I guess (2) should surely work. But is there any easy way of doing (1).
You can bundle arbitrary binaries with the --add-binary option on the command line or the binaries argument to the Analysis call in your .spec file. Check out the manual for details, but one example:
pyinstaller -F main.py --add-binary=`which redis-server`:bin
I don't know of a way to run arbitrary executables, but you could have some python code in your app to detect when you're bundled, find the redis binary, and start it up. Again, you can check out the documentation for details on how to go about this but, again, a example of how this could look (optional contextmanager elegance stolen from another answer):
import sys
import os
import subprocess
from contextlib import contextmanager
#contextmanager
def bundledredis():
proc = subprocess.Popen(
[os.path.join(sys._MEIPASS, 'bin', 'redis-server')])
yield
proc.terminate()
#contextmanager
def optional(condition, context_manager):
if condition:
with context_manager:
yield
else:
yield
def realmain():
print('doing stuff')
def main():
with optional(getattr(sys, 'frozen', False), bundledredis()):
realmain()
if __name__ == '__main__':
main()
I have 2 programs, one is calling the other through subprocess. Running this in pyCharm. My issue is that the call to the second program doesn't print out the desired string (see programs). What am I doing wrong, or is my understanding of the subprocess wrong?
this is something.py:
import subprocess
def func():
print("this is something")
sb = subprocess.call("diff.py", shell=True)
return sb
if __name__=="__main__":
func()
this is diff.py:
print("this is diff running")
def caller():
print("this is diff running called from name main")
if __name__=="__main__":
caller()
I decided to try subprocessing instead of importing for the purpose of running the calls concurrently in diff threads in the future. For now I just wanted to make sure I grasp subprocessing but I'm stuck at this basic level with this issue and get figure it out.
You must use python to run python files.
import subprocess
def func():
print("this is something")
sb = subprocess.call("python diff.py", shell=True)
# It is also important to keep returns in functions
return sb
if __name__=="__main__":
func()
I would be careful to understand the layout of how pycharm saves files. Maybe consider trying to run a program that already exists for the Windows command line if you are just trying to learn about the subprocess module.
import subprocess
print("this is where command prompt is located")
sb = subprocess.call("where cmd.exe", shell=True)
returns
this is where command prompt is located
C:\Windows\System32\cmd.exe
Thank you.
subprocess.call("python something.py", shell=True) now works as intended but for some reason the very same call from pyCharm does not return the second string from diff.py I assume the issue is with pyCharm then
To run diff.py script from the current directory using the same Python interpreter that runs the parent script:
#!/usr/bin/env python
import sys
from subprocess import check_call
check_call([sys.executable, 'diff.py'])
do not use shell=True unless it is necessary e.g., unless you need to run an internal command such as dir, you don't need shell=True in most cases
use check_call() instead of call() to raise an exception if the child script returns with non-zero exit code
Why[When] I try python something.py pyCharm fires up to interpret it.
You should associate .py extension with py (Python launcher). Though if running the command:
T:\> python something.py
literally brings up PyCharm with the file something.py opened instead of running the script using a Python interpreter then something is really broken. Find out what program is run then you type python (without arguments).
Make sure you understand the difference between:
subprocess.Popen(['python', 'diff.py'])
subprocess.Popen('diff.py')
subprocess.Popen('diff.py', shell=True)
os.startfile('diff.py')
os.startfile('diff.py', 'edit')
Try to run it from the command-line (cmd.exe) and from IDLE (python3 -m idlelib) and see what happens in each case.
You should prefer to import the Python module and use multiprocessing, threading modules if necessary to run the corresponding functions instead of running the Python script as a child process via subprocess module.
This is my code. I'm pretty new to this.
from subprocess import call
call(["cd", "/etc/apache2/"])
However, when this function is run, I get
Errno 2: No such file or directory
I am running Django within Apache*. This is my views.py file. Ask for additional code, and you shall receive.
edit - It should be noted that /etc/apache2/ does indeed exist.
If you want to change the working directory of the Python process you can use chdir from the os module:
import os
os.chdir('/etc/apache2')
First of all, you will not get what you expect if you run this. Try
import os
os.chdir('/etc/apache2')
Second, try /path/to/cd as process may not know cd alias.
I'm using sh in python 2.7.5 to call shell programs like curl and mkdir, but in PyDev plugin 2.7.5 under Eclipse 4.3.0. the following line gives an Unresolved Import error:
from sh import curl, printenv, mkdir, cat
I'm able to run the above code in a python shell. I do have the path to sh included in the Libraries pane in the Interpreter - Python window in Preferences, so I don't think that's the problem.
Try using the subprocess module to call console commands. For example:
from subprocess import call
dir_name = '/foo/bar/'
call('mkdir %s'%dir_name, shell=True)
Like Bill said, subprocess is a good choice here. I'd personally recommend using the Popen because it doesn't block, and allows you to wait for commands to finish with its communicate() method, which also returns stdout and stderr. Also, avoid using shell=True when possible. Usage:
import subprocess
testSubprocess = subprocess.Popen(['mkdir', dir_name], stdout=subprocess.PIPE)
testOut, testErr = testSubprocess.communicate()
when i login a remote server through ssh, i see the LD_LIBRARY_PATH was :
echo $LD_LIBRARY_PATH
:/usr/local/lib
And when i use fabric in python, to run the same code in fabric run api, the result is empty.
from fabric.api import *
def test():
run("echo $LD_LIBRARY_PATH")
and even when i try to change the LD_LIBRARY_PATH using fabric, it doesn't work at all.
from fabric.api import *
def test():
run("echo $LD_LIBRARY_PATH")
run("export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH")
Does anyone know why?
I had the same problem and here is a way to fix it. You need at least fabric 1.5.4 i think to use shell_env.
with shell_env(LD_LIBRARY_PATH ="/usr/local/lib"):
run('something')