python interative mode does not work when reading from std in - python

Given the following python script....
$ cat readStdin.py
#!/usr/bin/python
import sys
var = "".join(sys.stdin.readlines()).rstrip()
print var
... I get the follwing output:
$ echo hello | python -i readStdin.py
hello
>>>
$
... in other words it does not hang in the python console, but goes back to bash. Does anyone out there know how to make it stay in the python console???

Consider this -
$ echo print 4*2 | python -i
Python 2.7.2 (default, Jun 20 2012, 16:23:33)
Type "help", "copyright", "credits" or "license" for more information.
>>> 8
>>>
$
Echo produces print 4*2. Python even in interactive mode, considers this as input to be interpreted. Hence we see the 8 there. After this, the interpreter encounters an EOF, so it quits. Consider what you press to quit the interpreter - Ctrl+d or ^D. This is just another way to produce EOF on *nix.

Related

Self invocation of interactive shell through Python3 with bash

I am using python3 and subprocess.Popen to spawn a process of bash and invoking the Python3 interpreter again through the standard interpreter.
bash -i states:
-s If the -s option is present, or if no arguments remain after
option processing, then commands are read from the standard
input. This option allows the positional parameters to be
set when invoking an interactive shell.
This is a minimized example but it mainly bakes down to the following code:
import subprocess
import sys
p = subprocess.Popen(["bash", "-s"], stdin=subprocess.PIPE,stderr=sys.stderr, stdout=sys.stdout)
p.stdin.write(b"python3\n")
p.stdin.flush()
print("Done")
The output is simply "Done". Any suggestions how I need to handle the stdin pipes in order to let the interactive shell pop up inside the newly executed python3 interpreter?
Actual output
% python3 test.py
Done
Expected output:
% python3 test.py
Python 3.10.8 (main, Oct 13 2022, 10:17:43) [Clang 14.0.0 (clang-1400.0.29.102)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Newline character written to file with echo works in shell, but literal in Python 3

I'm on a Ubuntu 20.04 system, and I'm using Python 3.8 to write a script that does multiple things using configurable lines of bash, but one of them is that it creates desktop shortcuts.
This single-line command creates a desktop shortcut, and works flawlessly when I execute it directly in my terminal:
echo "[Desktop Entry]"$'\n'"Type=Application"$'\n'"Name[en_US]=Documents"$'\n'"Exec=pcmanfm ~/Documents"$'\n'"Icon=system-file-manager" > ~/Desktop/1;
However, when I execute it in Python, like so:
foobar.py
rl = """echo "[Desktop Entry]"$'\n'"Type=Application"$'\n'"Name[en_US]=Documents"$'\n'"Exec=pcmanfm ~/Documents"$'\n'"Icon=system-file-manager" > ~/Desktop/1;"""
subprocess.run(rl, shell=True)
...instead of creating a desktop shortcut with the proper name, icon, and action, it creates an empty file that contains the following text:
0.txt:
[Desktop Entry]$\nType=Application$\nName[en_US]=Sign Out$\nExec=/home/agent/QaSC/login/login.bin$\nIcon=system-switch-user
Is there any particular reason why Python would be handling the newline characters differently than the bash shell does, and if so, how can I resolve this problem?
$'...' is a bash extension, but the default shell used when shell=True is specified is sh. Use the executable option to specify an alternate shell.
subprocess.run(rl, shell=True, executable='/bin/bash')
Since the argument to echo has quotes, it could contain literal newlines at the command line, and therefore also in the Python process. I see no reason to use the Bash extension $'\n' syntax.
$ echo "foo
> bar"
foo
bar
$ python
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.run('echo "foo\nbar"', shell=True)
foo
bar
CompletedProcess(args='echo "foo\nbar"', returncode=0)
>>>
(It's also unclear why the Python code doesn't just write a file in the normal way, but I assume the command in the OP is essentially a placeholder.)

eshell starts python IDLE instead of running script when editing remotely

With Emacs 24.3.1, I get this when editing through Tramp/ssh in eshell:
/<remotepath> $ bash
/<remotepath> $ python test.py
hello world!
/<remotepath> $ exit
exit
/<remotepath> $ python test.py
Python 2.6.6 (r266:84292, Oct 12 2012, 14:23:48)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
The file test.py is:
print "hello world!"
Bash is version 4.1.2. Does anyone have any explanation for this behavior?
I don't know eshell, but my guess is you forget to pass the positional parameters when creating your alias:
# don't forget the quotes
# ▼ ▼
~ $ alias python '/path/to/alternate/python $*'
# ▲▲
# don't forget positional parameters
See http://www.emacswiki.org/emacs/EshellAlias

Is it possible to cross reference bash and python variables in python script

I can get a value n when I run a shell command using os.system in the python script, but I also need to sum it up to get a total number for subsequent computation in the python script,
total=0
for i in xrange(1,8):
os.system('n=$(qstat -n1 | grep -o node'+str(i)+' | wc -l) && echo $n')
Is it possible? Also is it possible to use python variable in shell command, something like
os.system('echo $total')
Use the shell's exportcommand:
$ export ABC=1 # Set and export var in shell
$ bash # Start another shell
$ echo $ABC # variable is still here
1
$ python # Start python still in the deeper shell
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from os import environ # import environnement
>>> environ['ABC'] # And here's the variable again (it's a string because the shell doesn't have types)
'1'
You can subprocess module's check_output method like this
import subprocess
print sum(int(subprocess.check_output(["/bin/sh", "-c", "n=`expr {} + 1` && echo $n".format(i)])) for i in range(10))
Output
55

Difference in SHA512 between python hashlib and sha512sum tool

I am getting different message digests from the linux 'sha512sum' tool and the python hashlib library.
Here is what I get on my Ubuntu 8.10:
$ echo test | sha512sum
0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123 -
$ python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> hashlib.sha512("test").hexdigest()
'ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff'
Both should calculate the message digest of the string "test", why do you think I am getting different results?
I think the difference is that echo adds a newline character to its output.
Try echo -n test | sha512sum
echo is adding a newline:
$ python -c 'import hashlib; print hashlib.sha512("test\n").hexdigest()'
0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123
To avoid that, use echo -n.
Different input, different output. Try comparing like with like:
C:\junk>echo test| python -c "import sys, hashlib; x = sys.stdin.read(); print len(x), repr(x); print hashlib.sha512(x).hexdigest()"
5 'test\n'
0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123

Categories

Resources