Recreating a shell-like interpreter within python? - python

Before I sit down and start hacking it out, I thought I'd come here and see if you all had any tips or even if something like this has been done before.
I want to re-create a basic shell like syntax within a python program. In other words, when people run the file with python, they will be greeted with a little prompt
>>
For simple things, using an option parser to say
opt.parse_args(input.split(" "))
Works just fine, but now I would like to not only escape special characters like spaces with the '\' character, but also treat quoted strings as a single argument, like in a unix shell.
Does there exist anything that might already help with this?
Thanks for any suggestions!
- Chase

Start with the shlex module:
$ pydoc shlex
Help on module shlex:
NAME
shlex - A lexical analyzer class for simple shell-like syntaxes.
You can use it like this:
>> import shlex
>> shlex.split('This "is a" test.')
['This', 'is a', 'test']
This just splits things up into logical tokens; it won't do anything like variable expansion and so forth. That's still up to you, as is actually running commands.

Have you seen shlex from the standard library? Check out this example.

Related

Python system argument reading '&'

I want to pass url to my python via the console and then do the appropriate tasks. many of the links contain the character '&' in the link. python interprets that as ending the argument this however is not what I want. here is a sample of the code
import sys
external_id = sys.argv[1].encode("utf-8")
print external_id
And when I run the following:
python graph.py 2%60&7
I get:
2%60
How do I make python interpret the '&' as nothing more than another character in the url?
This is not python, it's bash. You need to escape it:
python graph.py 2%60\&7
Quoting this answer:
The & informs the shell to put the command in the background.
Python never receives that character because the shell takes care of it, thus this isn't an issue of Python. You can also wrap 2%60&7 with quotes to make it work
me#pc:~$ python3 script.py '2%60&7'
b'2%60&7'
Sometimes escaping & is a lot harder than doing this.

How do I used 2 quotes in os.system? PYTHON

I have a little bit of problem when I'm trying to use 2 quotes in os.system..
I'm gonna launch a program with python, the directory has multiple spaces, and to launch something that has multiple spaces in CMD you need to put double quotes around it obviously.
And here comes the thingy..
my code looks like this:
import os
os.system("C:/t est/hello")
and since I used os.system, it will obviously just send C:/t est/hello that to CMD..
Now what I need is to send "C:/t est/hello" to cmd with quotes but I need python to understand that I need 2 quotes aswell. Can someone please help me?
If you want to add quotes to your command, simply do so. Possibly the easiest way is to use single quotes for your string:
os.system('"C:/t est/hello"')
If you want to write a double quote inside a string delimited by double quotes you need to escape it. That would be done like this:
os.system("\"C:/t est/hello\"")
However, it's just a lot easier to use subprocess instead and let it handle quoting for you. For example:
subprocess.check_call(['ls', 'some directory with spaces in'])
Even the documentation for os.system() recommends using subprocess:
The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

how does IPython's ? (question mark) operator actually work?

So i was thinking that in order to implement such a feature in a console application , where appending a question mark at the end of a function name will pour out it's doc string , i would have probably used a feature like metaclasses , where upon definition/import , i'd duplicate all the module member names and produce new ones just for typing out doc strings.
Then i noticed that you don't need actual parenthesis to call the helper functions and python doesn't actually allow you to put a question mark at the end of the function name anyway.... So is this done in python or am i just wasting my time trying to figure this out?
Thanks in advance
It's not done the way you're imagining. ipython reads your command prompt input as a line of text, so it has a chance to check if it ends with a question mark before it passes it on to eval (or whatever). If it does, it runs help(name) instead of what you typed.
AST looks a little heavy-duty, but you can get a feel for how this works by checking out the module code. It gives you a lightweight interpreter that you can extend with syntax of this sort if you want.
Have a look at the IPython.core.inputsplitter module for the code that parses the raw input line for things like ?, !, /, %, etc.
ipython uses AST, you can customize the syntax parsing and create a new ipython fork.
may help

Embedding executable python script in python string

If you are a bash/posix sh wizard you will know the $(command substition) feature in bash, which could even be inserted in a string. For example,
$ echo "I can count: $(seq 1 10 | tr -d '\n')"
I can count: 12345678910
You can imagine all wild things to do with this, especially to make a dynamically formed string. No need to do if..else block outside the string; just embed the code inside! I am s spoiled by this feature. So here's the question: in python, can we do something similar? Is there one person already devising a module to accomplish this task?
(Just a side comment: admittedly having this kind of feature is powerful but also opening yourself to a security risk. The program can be vulnerable to code injection. So think thoroughly before doing this especially with a foreign string coming from outside the code.)
You can use eval() and all of it's potential risks...
Some good links here and here
See the built-in eval() function.
Are you looking for an fstring:
Instead of starting the string with '
We start the string with f'
And whenever we want to embed any script we just put inside these: {}

Is it possible to access the source code of a python script passed to python on standard in?

This is a bit of a random question that is more out of curiosity than any specific need.
Is it possible to write some python code that will print some stuff out, including the source code itself, without having the python code stored in a file? For example, doing something like this at the Bash prompt:
$ echo '
> print "The Code:"
> PrintScript() # What would this function look like?
> for i in range(5):
> print i,
> print "!"
> ' | python
and get an output like this:
The Code:
print "The Code:"
PrintScript() # What would this function look like?
for i in range(5):
print i,
print "!"
0 1 2 3 4 5 !
I suspect that this probably can't be done, but given python's introspection capabilities, I was curious to know whether it extended to this level.
That's the closest I'm getting:
echo 'import __main__,inspect;print inspect.getsource(__main__)' | python
which fails... In any case, the original code is eaten up (read from stdin) by the interpreter at startup. At most you may be able to get to the compiled code, again through the __main__ module.
Update:
The dis module is supposed to give you a disassembly of all functions in a module, but even that one isn't seeing any code:
$ echo -e 'import __main__,dis;print dis.dis(__main__)' | python
None
And even when I throw in a function:
$ echo -e "import __main__,dis;print dis.dis(__main__)\ndef x():\n pass" | python
None
Yes, it is indeed possible to write a program which outputs it's own source. You don't need even introspection for this tasks, you just need to be able to print computed strings (works with every language).
The technique is called Quine and here is a rather short example in Python:
quine = 'quine = %r\r\nprint quine %% quine'
print quine % quine
But quines aren't limited to such simple programs. They can do much more, for example printing their own source backwards and so on... :)
print open(__file__).read(),
This will work on UNIX systems I think, but I'm not sure about Windows. The trailing comma makes sure that the source code is printed exactly, without an extra trailing newline.
Just realized (based on the comments below) that this does not work if your source code comes from sys.stdin, which is exactly what you were asking for. In that case, you might take advantage of some of the ideas outlined on this page about quines (programs printing their own source codes) in Python, but none of the solutions would be a single function that just works. A language-independent discussion is here.
So, in short, no, I don't think this is possible with a single function if your source code comes from the standard input. There might be a possibility to access the interpreted form of your program as a Python code object and translate that back into source form, but the translated form will almost surely not match the original file contents exactly. (For instance, the comments and the shebang line would definitely be stripped away).
closest you can get is using readline to interrogate the command history if available from what i can see e.g. but i suspect this may not contain stuff piped into the session and would only work for interactive sessions anyway

Categories