Skip to content

Instantly share code, notes, and snippets.

@zeroSteiner
Last active February 24, 2021 06:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeroSteiner/d34d662b0d13b53555be to your computer and use it in GitHub Desktop.
Save zeroSteiner/d34d662b0d13b53555be to your computer and use it in GitHub Desktop.
Python Bluetooth shell with PTY support
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# bt_shell.py
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Works with BlueTerm on Android
# https://play.google.com/store/apps/details?id=es.pymasde.blueterm&hl=en
#
# Author: Spencer McIntyre (@zeroSteiner)
import os
import pty
import uuid
import bluetooth
def child_process(sock):
os.dup2(sock.fileno(), 0)
os.dup2(sock.fileno(), 1)
os.dup2(sock.fileno(), 2)
os.putenv('HISTFILE', os.devnull)
pty.spawn(os.environ.get('SHELL', '/bin/sh'))
print('Disconnecting...')
sock.close()
os._exit(0)
def main():
server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
server_sock.bind(('', bluetooth.PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
random_uuid = str(uuid.uuid4())
bluetooth.advertise_service(server_sock,
'ShellServer',
service_id=random_uuid,
service_classes=[random_uuid, bluetooth.SERIAL_PORT_CLASS],
profiles=[bluetooth.SERIAL_PORT_PROFILE]
)
print("Waiting for connection on RFCOMM channel {0}".format(port))
while True:
try:
client_sock, (client_addr, client_ch) = server_sock.accept()
except KeyboardInterrupt:
break
print("Accepted connection from {0}".format(client_addr))
pid = os.fork()
if pid:
print("Forked shell process {0}".format(pid))
else:
child_process(client_sock)
client_sock.close()
print('Shutting down the server socket...')
server_sock.close()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment