Ubuntu – How to activate script on laptop from smartphone

emailiphoneremotescriptssmartphone

I want to run a linux script on my laptop remotely from my smartphone (iPhone, namely).
For simplicity let's say the script is called myscript.sh and it is located in /root/Desktop. I am running as root user (Yeah, I know what I am doing running as root.)

From the information I have gather these are the possible solutions:
1. Write some sort of app for iPhone to communicate (Sounds painstaking and too complex for me.)
2. Sending emails and using the "Procmail" thing
3. Sending emails and using the "Postfix" thing

All of the methods mentioned above are pretty unknown to me; I haven't heard of them until recently. So can anybody please enlighten me on ANY method that allow me to run a linux of my laptop from my smartphone.

Thank you!

EDIT: By the way, I have no servers running at home.

Best Answer

  • Option 1: SSH + ngrok

    1. I believe SSH server listening on 22 port comes by default on Ubuntu.
    2. Install ngrok with sudo apt-get install ngrok-client
    3. Sign up on ngrok.com to get an auth token (needed to use non-http protocols).
    4. Let local ngrok know about your account echo 'auth_token: YOUR_AUTH_TOKEN' > ~/.ngrok
    5. Run ngrok -proto=tcp 22

    You will get something like

    Tunnel Status                 online
    Version                       1.6/1.6
    Forwarding                    tcp://ngrok.com:52418 -> 127.0.0.1:22
    Web Interface                 127.0.0.1:4040
    # Conn                        0
    Avg Conn Time                 0.00ms
    

    ngrok.com:52418 is your local SSH server accessible from anywhere. By default port is given at random, but you can set it in config file. See docs for more info.

    Test it with ssh ngrok.com -p 52418. You can connect to it from any SSH client from your smartphone (I'm using VX ConnectBot) and do everything you can do with command line on your local computer, like executing scripts :]

    Option 2: Simple HTTP server + ngrok

    For simplified example I will create two files in ~/test/:

    • test.sh, which will output current timestamp and append it to log.txt:

      #! /bin/sh
      date +%s
      date +%s >> log.txt
      
    • server.py, which will wait for remote HTTP request and execute test.sh:

      #!/usr/bin/env python3
      import http.server, os, subprocess
      
      class HTTPRequestHandler(http.server.BaseHTTPRequestHandler):
          def do_GET(self):
      
              path = 'test.sh'
      
              # Make path absolute
              if path[0] != '/':
                  path = os.getcwd() + '/' + path
      
              # If file exists, execute it and return output
              if os.path.isfile(path):
                  if os.access(path, os.X_OK):
                      p = subprocess.Popen(path, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                      stdout, stderr = p.communicate()
                      content = stdout.decode('UTF-8')
                  else:
                      content = path + ' is not executable'
      
                  self.send_response(200)
                  self.send_header('Content-type', 'text/html')
                  self.end_headers()
                  self.wfile.write(content.encode('UTF-8'))
      
              else:
                  self.send_header('Content-type', 'text/html')
                  self.send_response(404, 'File Not Found')
                  self.end_headers()
      
      PORT = 8000
      handler_class = HTTPRequestHandler
      httpd = http.server.HTTPServer(('', PORT), handler_class)
      
      print('Listening at port', PORT)
      
      try:
          httpd.serve_forever()
      except KeyboardInterrupt:
          pass
      
      httpd.server_close()
      print('Server stopped')
      

    Now we can make server.py executable, run it, then open http://127.0.0.1:8000 in a browser and see that script actually worked — it will output current timestamp in our browser window + append it to ~/test/log.txt.

    But 127.0.0.1 is just localhost, and we want to reach our server from internet. That's where ngrok comes in. Install it with sudo apt-get install ngrok-client and execute ngrok 8000, it will give you something like:

    Tunnel Status                 online
    Version                       1.6/1.6
    Forwarding                    http://a1b2c3d4.ngrok.com -> 127.0.0.1:8000
    Forwarding                    https://a1b2c3d4.ngrok.com -> 127.0.0.1:8000
    Web Interface                 127.0.0.1:4040
    # Conn                        0
    Avg Conn Time                 0.00ms
    

    That https://a1b2c3d4.ngrok.com is public address (i.e. accessible from internet) which will be actually served by your local server (which will execute your script, as you remember :)). By default subdomain name is given at random, but you can set it in config file. See docs for more info.

    You can run both your server and ngrok in background, but that is another story :]

    Option 3: TeamViewer (or VNC + ngrok)

    You can even have full graphic remote control with TeamViewer host on your laptop and TeamViewer client app on your smartphone. Easy, but could be too traffic consuming for mobile use.

    Instead of TeamViewer, you could probably use VNC server + ngrok on your laptop and VNC client on your smartphone.

  • Related Question