Creating a CLI (Shell?) in Python - python

I am very newbie in Python but I have to implement for school a command line interpreter in Python language, but I am kinda lost in how to do that.
I have already read some tutorials and created a simple file called functions.py where i include some simple functions like this:
def delete(loc):
if os.path.exists(loc) == True:
os.remove(loc)
print "Removed"
else:
print "File not exists"
Now.. here is the thing.. in order to use this I must import it inside the python command interpreter, like...
import functions
functions.delete("file to delete")
How can I make a Shell/CLI so instead of have to write all of this I can just write like:
delete file_name
Thanks!

Or if you want a cmd shell, you could use the cmd lib. It offers python interfaces to making command lines.
http://docs.python.org/library/cmd.html

I think you should now to use simple argparse module to get command line arguments
import argparse
from functions import delete
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file')
args = parser.parse_args()
delete(args.file)
Hope this should work for you
Sultan

You might want to check my personal REPL for some inspiration. I wrote it during a tutorial series. Actual source may be found here. It probably does a few things you won't need... Still it could be a good read. :)

Related

Using Jenkins variables/parameters in Python Script with os.path.join

I'm trying to learn how to use variables from Jenkins in Python scripts. I've already learned that I need to call the variables, but I'm not sure how to implement them in the case of using os.path.join().
I'm not a developer; I'm a technical writer. This code was written by somebody else. I'm just trying to adapt the Jenkins scripts so they are parameterized so we don't have to modify the Python scripts for every release.
I'm using inline Jenkins python scripts inside a Jenkins job. The Jenkins string parameters are "BranchID" and "BranchIDShort". I've looked through many questions that talk about how you have to establish the variables in the Python script, but with the case of os.path.join(),I'm not sure what to do.
Here is the original code. I added the part where we establish the variables from the Jenkins parameters, but I don't know how to use them in the os.path.join() function.
# Delete previous builds.
import os
import shutil
BranchID = os.getenv("BranchID")
BranchIDshort = os.getenv("BranchIDshort")
print "Delete any output from a previous build."
if os.path.exists(os.path.join("C:\\Doc192CS", "Output")):
shutil.rmtree(os.path.join("C:\\Doc192CS", "Output"))
I expect output like: c:\Doc192CS\Output
I am afraid that if I do the following code:
if os.path.exists(os.path.join("C:\\Doc",BranchIDshort,"CS", "Output")):
shutil.rmtree(os.path.join("C:\\Doc",BranchIDshort,"CS", "Output"))
I'll get: c:\Doc\192\CS\Output.
Is there a way to use the BranchIDshort variable in this context to get the output c:\Doc192CS\Output?
User #Adonis gave the correct solution as a comment. Here is what he said:
Indeed you're right. What you would want to do is rather:
os.path.exists(os.path.join("C:\\","Doc{}CS".format(BranchIDshort),"Output"))
(in short use a format string for the 2nd argument)
So the complete corrected code is:
import os
import shutil
BranchID = os.getenv("BranchID")
BranchIDshort = os.getenv("BranchIDshort")
print "Delete any output from a previous build."
if os.path.exists(os.path.join("C:\\Doc{}CS".format(BranchIDshort), "Output")):
shutil.rmtree(os.path.join("C:\\Doc{}CS".format(BranchIDshort), "Output"))
Thank you, #Adonis!

Python - How to take input from command line and pipe it into socket.gethostbyaddr("")

I have been scouring the internet looking for the answer to this. Please not my python coding skills are not all that great. I am trying to create a command line script that will take the input from the command line like this:
$python GetHostID.py serverName.com
the last part is what I am wanting to pass on as a variable to socket.gethostbyaddr("") module. this is the code that I have so far. can someone help me figure out how to put that variable into the (" "). I think the "" is creating problems with using a simple variable name as it is trying to treat it as a string of text as appose to a variable name.
here is the code I have in my script:
#!/bin/python
#
import sys, os
import optparse
import socket
remoteServer = input("Enter a remote host to scan: ")
remoteServerIP = socket.gethostbyaddr(remoteServer)
socket.gethostbyaddr('remoteServer')[0]
os.getenv('remoteServer')
print (remoteServerIP)
any help would be welcome. I have been racking my brain over this...
thanks
The command line arguments are available as the list sys.argv, whose first element is the path to the program. There are a number of libraries you can use (argparse, optparse, etc.) to analyse the command line, but for your simple application you could do something like this:
import sys
import sys, os
import optparse
import socket
remoteServer = sys.argv[1]
remoteServerIP = socket.gethostbyaddr(remoteServer)
print (remoteServerIP)
Running this program with the command line
$ python GetHostID.py holdenweb.com
gives the output
('web105.webfaction.com', [], ['108.59.9.144'])
os.getenv('remoteserver') does not use the variable remoteserver as an argument. Instead it uses a string 'remoteserver'.
Also, are you trying to take input as a command line argument? Or are you trying to take it as user input? Your problem description and implementation differ here. The easiest way would be to run your script using
python GetHostID.py
and then in your code include
remoteServer = raw_input().strip().split()
to get the input you want for remoteserver.
you can use sys.argv
for
$python GetHostID.py serverName.com
sys.argv would be
['GetHostID.py', 'serverName.com']
but for being friendly to the user have a look at the argparse Tutorial
In Python 2, input reads text and evaluates it as a Python expression in the current context. This is almost never what you want; you want raw_input instead. However, in Python 3, input does what raw_input did in version 2, and raw_input is not available.
So, if you need your code to work in both Python 2 and 3, you should do something like this after your imports block:
# Apply Python 3 semantics to input() if running under v2.
try:
input = raw_input
def raw_input(*a, **k):
raise NameError('use input()')
except NameError:
pass
This has no effect in Python 3, but in v2 it replaces the stock input with raw_input, and raw_input with a function that always throws an exception (so you notice if you accidentally use raw_input).
If you find yourself needing to smooth over lots of differences between v2 and v3, the python-future library will probably make your life easier.

Call a python main from another python script

I have been giving some huge command line tool from a colleague. The main reads a bunch of arguments, parses those using the elegant import OptionParser later on and does the job.
if __name__ == '__main__':
main(sys.argv)
I can either dig into the code and copy paste loads of code, or find a way to use a "command line" call from my python script. I guess the second option is preferrable as it prevents me from randomly extracting code. Would you agree ?
You don't need to do cut and paste or launch a new Python interpreter. You should be able to import the other script.
For example, if your colleague's script is called somescript.py you could do:
import somescript
args = ['one','two']
somescript.main(args)

How can I add a command to the Python interactive shell?

I'm trying to save myself just a few keystrokes for a command I type fairly regularly in Python.
In my python startup script, I define a function called load which is similar to import, but adds some functionality. It takes a single string:
def load(s):
# Do some stuff
return something
In order to call this function I have to type
>>> load('something')
I would rather be able to simply type:
>>> load something
I am running Python with readline support, so I know there exists some programmability there, but I don't know if this sort of thing is possible using it.
I attempted to get around this by using the InteractivConsole and creating an instance of it in my startup file, like so:
import code, re, traceback
class LoadingInteractiveConsole(code.InteractiveConsole):
def raw_input(self, prompt = ""):
s = raw_input(prompt)
match = re.match('^load\s+(.+)', s)
if match:
module = match.group(1)
try:
load(module)
print "Loaded " + module
except ImportError:
traceback.print_exc()
return ''
else:
return s
console = LoadingInteractiveConsole()
console.interact("")
This works with the caveat that I have to hit Ctrl-D twice to exit the python interpreter: once to get out of my custom console, once to get out of the real one.
Is there a way to do this without writing a custom C program and embedding the interpreter into it?
Edit
Out of channel, I had the suggestion of appending this to the end of my startup file:
import sys
sys.exit()
It works well enough, but I'm still interested in alternative solutions.
You could try ipython - which gives a python shell which does allow many things including automatic parentheses which gives you the function call as you requested.
I think you want the cmd module.
See a tutorial here:
http://wiki.python.org/moin/CmdModule
Hate to answer my own question, but there hasn't been an answer that works for all the versions of Python I use. Aside from the solution I posted in my question edit (which is what I'm now using), here's another:
Edit .bashrc to contain the following lines:
alias python3='python3 ~/py/shellreplace.py'
alias python='python ~/py/shellreplace.py'
alias python27='python27 ~/py/shellreplace.py'
Then simply move all of the LoadingInteractiveConsole code into the file ~/py/shellreplace.py Once the script finishes executing, python will cease executing, and the improved interactive session will be seamless.

How to Pass variables to python script?

I know it can be achieved by command line but I need to pass at least 10 variables and command line will mean too much of programming since these variables may or may not be passed.
Actually I have build A application half in vB( for GUI ) and Half in python( for script ). I need to pass variables to python, similar, to its keywords arguments, i.e, x = val1, y = val2. Is there any way to achieve this?
If you are using Python <2.7 I would suggest optparse.
optparse is deprecated though, and in 2.7 you should use argparse
It makes passing named parameters a breeze.
you can do something fun like call it as
thepyscript.py "x = 12,y = 'hello world', z = 'jam'"
and inside your script,
parse do:
stuff = arg[1].split(',')
for item in stuff:
exec(item) #or eval(item) depending on how complex you get
#Exec can be a lot of fun :) In fact with this approach you could potentially
#send functions to your script.
#If this is more than you need, then i'd stick w/ arg/optparse
Since you're working on windows with VB, it's worth mentioning that IronPython might be one option. Since both VB and IronPython can interact through .NET, you could wrap up your script in an assembly and expose a function which you call with the required arguments.
Have you taken a look at the getopt module? It's designed to make working with command line options easier. See also the examples at Dive Into Python.
If you are working with Python 2.7 (and not lower), than you can also have a look at the argparse module which should make it even easier.
If your script is not called too often, you can use a configuration file.
The .ini style is easily readable by ConfigParser:
[Section_1]
foo1=1
foo2=2
foo3=5
...
[Section_2]
bar1=1
bar2=2
bar3=3
...
If you have a serious amount of variables, it might be the right way to go.
What do you think about creating a python script setting these variables from the gui side? When starting the python app you just start this script and you have your vars.
Execfile

Categories

Resources