Can python shell have some pre-input? - python

When testing in python shell, I always have to type some import like:
Python 2.5.4 (r254:67916, Jun 24 2010, 15:23:27)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>import sys
>>>import datetime
Can someone help me to automatically finish these? It means I run some command to enter python shell it has already done import for me, and a python shell waiting for me to continue type command.
Thanks.

Try:
python -i -c "import sys; import datetime;"
More info:
-i : inspect interactively after running script; forces a prompt even
if stdin does not appear to be a terminal; also PYTHONINSPECT=x
&
-c cmd : program passed in as string (terminates option list)

Create a file with the commands you want to execute during startup, and set the environment variable PYTHONSTARTUP to the location of that file. The interactive interpreter will then load and execute that file. See http://docs.python.org/tutorial/interpreter.html#the-interactive-startup-file
On a sidenote, you might want to consider ipython as an improved Python shell when working in interactive mode.

Related

Why doesn't python send output to stdout?

Here's a minimum working example (MWE), saved as mwe.py:
import sys
def f(n):
print("Testing print()...")
sys.stdout.write("Calculating f({})...".format(n))
When run from the command line I get no output whatsoever:
username#hostname:~/mydir$ python mwe.py 'f(99)'
username#hostname:~/mydir$
When run from within python
I get output (some info removed):
username#hostname:~/mydir$ python
Python 3.5.4 (default, DATE, HH:MM:SS)
[GCC X.X.X Compatible Apple LLVM X.X.X (clang-X.X.X)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from mwe import f
>>> f(99)
Testing print()...
Calculating f(99)...
>>>
Why do these output statements work within python but not from the command line?
python mwe.py 'f(99)' doesn't mean "run the f function from mwe.py with argument 99". If you wanted to do that from the command line, you could execute
python -c 'import mwe; mwe.f(99)'
python mwe.py 'f(99)' means "run the script mwe.py with sys.argv[1] set to the string "f(99)"". The script mwe.py doesn't examine sys.argv or print anything at all; it just defines a function and ends.
This: python mwe.py 'f(99)' just shouldn't work. In this case, 'f(99)' is just passed as an argument to the program.
Try using python -c 'import mwe; mwe.f(99) instead. (also read more about command line usage of python by typing python -h)

Starting a python shell with arguments

is it possible to pass arguments to the python in linux without having a file? I'm currently not able to create a file or change permissions and I don't want to write it inside my code like this:
import sys
sys.argv = ["arg1", "arg2", ...]
I'd like to hand over the arguments while I'm starting the shell:
python <arguments>
While is is questionable if passing commands line arguments to an interactive shell is best practice, it is indeed possible by passing - instead of the the scripts file name:
$ python - a1 a2
Python 2.7.14 (default, Sep 23 2017, 22:06:14)
[GCC 7.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.argv
['-', 'a1', 'a2']
If you are using IPython as interactive shell, you can pass arguments to scripts you run using the %run magic command:
In [1]: %run myscript.py arg1 arg2 ...
(It's not really clear to me what you are trying to achieve, but you probably want to pass the arguments to some script.)

How do I get the shell variable value in Popen

I'm trying to pass some secrets to shell commands using environment variables. The Popen seems using "single quote concept" to escape the arguments so the commands cannot get the variable value.
Python 2.7.1 (r271:86832, Mar 3 2017, 10:25:58)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux3
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.Popen(['echo','$PATH'])
$PATH
Expected output is the real $PATH values like "/bin:/sbin:/usr/bin..."
Thanks!
You need a shell to evaluate your line:
subprocess.Popen('echo $PATH', shell=True)
But if this is all you want then consider this:
print os.getenv('PATH')
Use shell=True, but be careful https://docs.python.org/3/library/subprocess.html#security-considerations
subprocess.Popen('echo $PATH', shell=True)
Using shell is dangerous if the command line is filed from external sources, so use it with caution.
Also, there is an optional parameter to decide where the shell should be when launching the command.
command = 'echo $PATH'
p = subprocess.Popen(command, shell=True, cwd='./')
p.communicate() # it would wait until the subprocess is complete.

Shebang for scripts not working

I am using PythonAnyhwere for my django production environment. I have a script which should run on scheduled basis.
Since I installed django in a virtualenv, the script starts like
#!/usr/bin/env python
activate_this = '/home/myname/.virtualenvs/myenv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
The error I get for this is
/usr/bin/env python: no such Python interpreter
No problem. So I changed it to
#!/usr/bin/env python2.7
Then I got
/usr/bin/env python2.7: no such Python interpreter
or
/usr/bin/env python3.4: no such Python interpreter
I said ok, what if I don't have a shebang line at all?
Error in log:
line 1: activate_this: command not found
line 2: syntax error near unexpected token `activate_this,'
line 2: `execfile(activate_this, dict(__file__=activate_this))'
What is the way then?
You can know where your Python interpreter by typing
$ which python
Also you try something like this (or maybe without env):
$ env python
Python 3.5.0 (default, Sep 20 2015, 11:28:25)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path
<module 'posixpath' from '/usr/lib/python3.5/posixpath.py'>
And then change lib to bin and omit /posixpath.py part

stdin reading blocking when running sbt with python subprocess.Popen()

I'm launching sbt via Popen(), and my python process stdin reading is not working.
Here is an example:
On the first line I'm launching Popen, on the second line I'm trying to browse throught the history with an arrow key. This does not work for some time, printing ^[[A.
$ python
Python 2.7.10 (default, Jul 13 2015, 12:05:58)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess; f = open("/dev/null", "rw"); subprocess.Popen(["sbt"], stdout=f, stderr=f, stdin=f)
<subprocess.Popen object at 0x10fc03950>
>>> ^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[Aimport subprocess; f = open("/dev/null", "rw"); subprocess.Popen(["sbt"], stdout=f, stderr=f, stdin=f)
This seems to only happen with sbt.
Any idea why and how to bypass this behavior ?
Thanks
My guess is that sbt is misbehaving when there is no pseudo-tty to interact with the user (probably because of jline).
Hence, let's use a python module to run the commands in a pseudo-tty. Install pexpect via pip (pip3 install pexpect for Python 3.x).
Then, run the following:
import pexpect, sys
f = open("sbt.log", "w+")
# Use `spawnu` for Python3, `spawn` otherwise
sbt = pexpect.spawnu("sbt -Dsbt.log.noformat=true \"version\" \"another-command\"", logfile=f)
# Do whatever is needed while sbt is running
# Force the process to expect EOF and file to be written
sbt.expect(pexpect.EOF)
Tested in Python 3.4.3 (Gentoo Linux) and works.

Categories