I have my fabfile.py like this. this I run with 'fab2 deploy` in command line.
from fabric2 import task
hosts = ["host1"]
#task(hosts=hosts)
def deploy(c):
with c.cd("/tmp"):
c.run("uptime")
if __name__ == "__main__":
deploy()
Like to run this code with-in python program like python3 fabfile.py. but its giving the error message.
if not isinstance(args[0], Context):
IndexError: tuple index out of range
Is it possible to call with python code?
Thanks
Related
I am trying to run a python script within another python script. Which will run 10 times and produce 10 outputs.
I want to run program1.py inside program2.py. Now my program1.py was initially taking a C executable inside it and it takes 1 command line argument.
The program1.py looks like below:
import os
import sys
dataset = sys.argv[1]
os.system(f"/home/Dev/c4.5 -u -f {dataset}")
os.system(f"/home/Dev/c4.5rules -u -f {dataset}")
os.system(f"/home/Dev/c4.5rules -u -f {dataset} > Temp")
f = open('Temp')
# Some code
Where c4.5 and c4.5rules are the name of the executable files. To run this I was using python3 program1.py dataset_name
Now I am trying to put this program1.py inside program2.py and I am trying this below approach:
import os
import subprocess
# Some code
for track in range(0, 10):
with open(f'Train_{track}', 'r') as firstfile, open(f'DF_{track}.data', 'w') as secondfile:
for line in firstfile:
secondfile.write(line)
os.system("/home/Dev/program1.py DF_track")
#subprocess.Popen("/home/Dev/program1.py DF_track", shell=True)
Where I simply want to get the output of program1.py 10 times and want to use DF_track as the command line input for each output generation.
Using above approach I am getting lots of error. Please help.
Edit_1 :
Actually whenever I am trying to run, my cursor is not working, it is freezing, so unable to copy the errors.
Here are some of them :
1. attempt to perform an operation not allowed by security policy.
2. syntax error : word expected (expecting ")")
Imagine I have 2 files, the first file is a.py and the other is b.py and I want to call the a.py from b.py.
The content of a.py is:
print('this is the a.py file')
and the content of b.py is:
import os
stream = os.popen('python3 a.py')
output = stream.read()
print(output)
Now when I call b.py from terminal I get the output I expect which is a.py print statment
user#mos ~ % python3 b.py
this is the a.py file
You can do this with subprocess too instead of os module.
Here is a nice blog I found online where I got the code from: https://janakiev.com/blog/python-shell-commands/
See the example below.
a.py
def do_something():
pass
b.py
from a import do_something
do_something()
I'm working with Django and I'd created two database. Everything seems to work fine, but then I had to edit one of the two and add a column.. From that moment the db wouldn't work anymore, so I exported in a text file the first database and thinking "now I recreate the two db and run a python script to refill the first one". The problem is that whene I try to run the script I get errors, because I can't run the command like bash using os.system, and I don't really know any other way... So, here's my code:
import os
def func ():
try:
FILE=open ("./languagedb.txt", "r")
except IOError:
print 'Can\'t open db file'
exit (1)
for line in FILE:
if (line.startswith('INSERT')):
values=line[43:-1]
language=values[1:3]
values=values[6:]
field=""
fieldBool=True
i=0
while fieldBool:
try:
c=values[i]
except:
print ''
if c != '\'':
field=field+str(c)
i=i+1
else:
fieldBool=False
values=values [(i+3):]
text=""
textBool=True
i=0
while textBool:
try:
c=values[i]
except:
print ''
if c != '\'':
text=text+str(c)
i=i+1
else:
textBool=False
comand="Language.objects.create(language=\""+language+"\", text=\""+text+"\", campo=\""+field+"\")"
os.system(comand)
This is the way I call the shell:
python manage.py shell
and the commands I give it:
import django
from languageMods.models import *
import mymigration #The name fo the file containing the above code
mymigration.func()
And I get the following error, for example
sh: -c: line 0: syntax error near unexpected token `language="en",'
Which is shell's error.
Does someone know how to execute a command from a python script in a python shell?
If you start your script the way you describe it you can just call the django DB API directly in your code:
Language.objects.create(language=language, text=text, campo=field)
I am trying to write a python CLI program using module python cmd. When I try to execute another python script in my CLI program my objective is I have some python script in other folder and CLI program in other folder. I am trying to execute those python script using CLI program.
Below is the os.popen method used to execute other script there is CLI program:
import cmd
import os
import sys
class demo(cmd.Cmd):
def do_shell(self,line,args):
"""hare is function to execute the other script"""
output = os.popen('xterm -hold -e python %s' % args).read()
output(sys.argv[1])
def do_quit(self,line):
return True
if __name__ == '__main__':
demo().cmdloop()
and hare is error:
(Cmd) shell demo-test.py
Traceback (most recent call last):
File "bemo.py", line 18, in <module>
demo().cmdloop()
File "/usr/lib/python2.7/cmd.py", line 142, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python2.7/cmd.py", line 221, in onecmd
return func(arg)
TypeError: do_shell() takes exactly 3 arguments (2 given)
there is some link to other cmd CLI program
1 = cmd – Create line-oriented command processors
2 = Console built with Cmd object (Python recipe)
and some screen shot's for more information:
Please run above code in your system.
As specified in the doc:
https://pymotw.com/2/cmd/index.html
do_shell is defined as such:
do_shell(self, args):
But you are defining it as
do_shell(self, line, args):
I think the intended use is define it as specified from the documentation.
I ran your code and followed your example. I replicated your error. I then, as specified in the documentation for do_shell, I changed the method to the as expected:
do_shell(self, args):
From there, the sys module was missing, so you need to import that as well (unless you did not copy it from your source). After that, I got an error for index out of range, probably because of the expectation of extra parameters needing to be passed.
Furthermore, because you are talking about Python scripts, I don't see the need for the extra commands you are adding, I simply changed the line to this:
output = os.popen('python %s' % args).read()
However, if there is a particular reason you need the xterm command, then you can probably put that back and it will work for your particular case.
I also, did not see the use case for this:
output(sys.argv[1])
I commented that out. I ran your code, and everything worked. I created a test file that just did a simple print and it ran successfully.
So, the code actually looks like this:
def do_shell(self, args):
"""hare is function to execute the other script"""
output = os.popen('python %s' % args).read()
print output
The full code should look like this:
import cmd
import os
import sys
class demo(cmd.Cmd):
def do_shell(self, args):
"""hare is function to execute the other script"""
output = os.popen('python %s' % args).read()
print output
def do_quit(self,line):
return True
if __name__ == '__main__':
demo().cmdloop()
I built this little program called Assembler.py:
def main(argv):
temp = os.path.realpath(argv[1])
if temp.endswith(".asm"):
print(temp)
else:
print("submit a valid file")
if __name__ == "__main__":
main(sys.argv)
I'm running this with some script I built:
python Assembler.py $1
example for running:
Assembler pong.asm
I don't know why if is wrong. Why my address is not ending with .asm ?
Your all code like this:
#coding=utf-8
import os
import sys
def main(argv):
temp = os.path.realpath(argv[1])
if temp.endswith(".asm"):
print(temp)
else:
print("submit a valid file")
if __name__ == "__main__":
main(sys.argv)
Then, you should use python Assembler pong.asm directly.
Example:
C:\Users\ou\Desktop\test>python test.py xyz.asm
C:\Users\ou\Desktop\test\xyz.asm
There is nothing wrong with the if. The problem is with the shell script and the way you are trying to run it.
If you want to run your python code directly you should run
python Assembler.py pong.asm
The .py extension is important!
If you want to write simple shell script to wrap that. You can create file named Assembler with following content:
python Assembler.py $1
To run that simple shell script you should run:
./Assembler pong.asm
or
sh Assembler pong.asm
Where ./ or sh is required.
I cannot get fabric working when used as a library within my own python scripts. I made a very short example fabfile.py to demonstrate my problem:
#!/usr/bin/env python
from fabric.api import *
print("Hello")
def test():
with settings(host_string='myIp', user="myUser", password="myPassword"):
run("hostname")
if __name__ == '__main__':
test()
Running fab works like a charm:
$ fab test
Hello
[myIp] run: hostname
[myIp] out: ThisHost
[myIp] out:
Done.
Disconnecting from myUser#myIp... done.
Ok, now, running the python script without fab seems to break somewhere:
$ python fabfile.py
Hello
[myIp] run: hostname
It immediatly returns, so it does not even seem to wait for a response. Maybe there are errors, but I don't see how to output those.
I am running this script inside my vagrant virtual machine. As fab executes without any errors, I guess this should not be a problem!
UPDATE
The script seems to crash as it does not execute anything after the first run. local on the other hand works!
We executed the script on a co-workers laptop and it runs without any issues. I am using Python 2.6.5 on Ubuntu 10.04 with fabric 1.5.1, so I guess there is a problem with some of this! Is there any way to debug this properly?
I've experienced a similar issue, that the fab command exited without error but just a blank line on the first run()/sudo() command.
So I put the run() command into a try: except: block and printed the traceback:
def do_something():
print(green("Executing on %(host)s as %(user)s" % env))
try:
run("uname -a")
except:
import traceback
tb = traceback.format_exc()
print(tb)
I saw that it the script exited in the fabfile/network.py at line 419 when it caught an EOFError or TypeError. I modified the script to:
...
except (EOFError, TypeError) as err:
print err
# Print a newline (in case user was sitting at prompt)
print('')
sys.exit(0)
...
which then printed out:
connect() got an unexpected keyword argument 'sock'
So I remove the sock keyword argument in the connect method a few lines above and it worked like charm. I guess it is a problem with a paramiko version, that does not allow the sock keyword.
Versions:
Python 2.7.3
Fabric >= 1.5.3
paramiko 1.10.0
if you look at the fab command it looks like this:
sys.exit(
load_entry_point('Fabric==1.4.3', 'console_scripts', 'fab')()
)
this means it looks for a block labeled console_scripts in a file called entry_points.txt in the Fabric package and executes the methods listed there, in this case fabric.main:main
when we look at this method we see argument parsing, interesting fabfile importing and then:
if fabfile:
docstring, callables, default = load_fabfile(fabfile)
state.commands.update(callables)
....
for name, args, kwargs, arg_hosts, arg_roles, arg_exclude_hosts in commands_to_run:
execute(
name,
hosts=arg_hosts,
roles=arg_roles,
exclude_hosts=arg_exclude_hosts,
*args, **kwargs
)
with some experimentation we can come up with something like:
from fabric import state
from fabric.api import *
from fabric.tasks import execute
from fabric.network import disconnect_all
def test():
with settings(host_string='host', user="user", password="password"):
print run("hostname")
if __name__ == '__main__':
state.commands.update({'test': test})
execute("test")
if state.output.status:
print("\nDone.")
disconnect_all()
which is obviously very incomplete, but perhaps you only need to add the
disconnect_all()
line at the end of your script