Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Hermann-SW
Last active December 6, 2022 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hermann-SW/65e07365cc2586b76afb6274ece12d5b to your computer and use it in GitHub Desktop.
Save Hermann-SW/65e07365cc2586b76afb6274ece12d5b to your computer and use it in GitHub Desktop.
Remote control bash from Python
from subprocess import Popen, PIPE
from sys import argv
import re
stop = "qwertz1234567890ufugUUGUGUgUgUGuGFzR775§%!=%%54321rUF/Rtt8t8TTT4§2hj\n"
bye = ["tschüs","do_widzenia","ahoj","ciao","salut","adieu","vaarwel","farvel"]
byes = re.sub(r"['[]]*", "", str(bye))
cmd = "bash" if len(argv) == 1 else argv[1]
p = Popen(cmd, stdin=PIPE, stdout=PIPE)
while True:
i = input(cmd + ": ")
if i in bye: break
if i == "?":
print("'cmd' gets executed\n'?' for this help\nto exit, any of: "+byes)
continue
p.stdin.write(bytes(i + "\necho " + stop, 'utf-8')); p.stdin.flush()
while True:
resp = p.stdout.readline().decode(encoding="utf-8")
if resp == stop: break
print(resp, end="")
@Hermann-SW
Copy link
Author

Popen communicate() is no option for this application.
All .poll() code I found did not do what is needed.
That is the reason this script uses the "stop" line trick for dealing with multi line responses:

pi@pi400-64:~ $ python bash_.py 
bash: ls -l .local
total 16
drwxr-xr-x  2 pi pi 4096 Dec  5 23:16 bin
drwxr-xr-x  4 pi pi 4096 Feb 20  2022 etc
drwxr-xr-x  3 pi pi 4096 Feb 20  2022 lib
drwxr-xr-x 18 pi pi 4096 Dec  5 10:49 share
bash: pwd
/home/pi
bash: uname -r -m -o
5.15.76-v8+ aarch64 GNU/Linux
bash: 

'?' help is builtin, exit of bash_.py with German "tschüs",
or any of the Germany neighbor country's languages word for "bye" (in clockwise map order):

bash: ?
'cmd' gets executed
'?' for this help
to exit, any of: tschüs, do_widzenia, ahoj, ciao, salut, adieu, vaarwel, farvel
bash: tschüs
pi@pi400-64:~ $ 

Long responses just work:

bash: man tee
TEE(1)                           User Commands                          TEE(1)

NAME
       tee - read from standard input and write to standard output and files

SYNOPSIS
       tee [OPTION]... [FILE]...

DESCRIPTION
       Copy standard input to each FILE, and also to standard output.

       -a, --append
              append to the given FILEs, do not overwrite

       -i, --ignore-interrupts
              ignore interrupt signals

       -p     diagnose errors writing to non pipes

       --output-error[=MODE]
              set behavior on write error.  See MODE below

       --help display this help and exit

       --version
              output version information and exit

   MODE determines behavior with write errors on the outputs:
       'warn' diagnose errors writing to any output

       'warn-nopipe'
              diagnose errors writing to any output not a pipe

       'exit' exit on error writing to any output

       'exit-nopipe'
              exit on error writing to any output not a pipe

       The default MODE for the -p option is 'warn-nopipe'.  The default oper‐
       ation when --output-error is not specified, is to exit  immediately  on
       error  writing  to a pipe, and diagnose errors writing to non pipe out‐
       puts.

AUTHOR
       Written by Mike Parker, Richard M. Stallman, and David MacKenzie.

REPORTING BUGS
       GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
       Report any translation bugs to <https://translationproject.org/team/>

COPYRIGHT
       Copyright © 2020 Free Software Foundation, Inc.   License  GPLv3+:  GNU
       GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
       This  is  free  software:  you  are free to change and redistribute it.
       There is NO WARRANTY, to the extent permitted by law.

SEE ALSO
       Full documentation <https://www.gnu.org/software/coreutils/tee>
       or available locally via: info '(coreutils) tee invocation'

GNU coreutils 8.32              September 2020                          TEE(1)
bash: 

@Hermann-SW
Copy link
Author

Hermann-SW commented Dec 6, 2022

If responses are known to be 1 line always, much simpler bash1.py can be used:
https://gist.github.com/Hermann-SW/4c5b204f2eecf712b568bf85ee111a2b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment