3

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.

2
  • 1
    For Android there is connectbot which provides you with SSH. Maybe such exists for IOS? You could also run a simple Webserver that calls your script. What does your script do?
    – user314111
    Aug 9 '14 at 19:45
  • You could install Apache and run your script as CGI.
    – kraxor
    Aug 9 '14 at 20:10
2

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.

7
  • How do I do this? Sorry, but I am pretty new to this mobile thing-y. Can you please provide more details for me? Thanks.
    – krismath
    Aug 10 '14 at 2:32
  • Updated answer with an example.
    – Shevchuk
    Aug 11 '14 at 14:43
  • Added two more options
    – Shevchuk
    Aug 12 '14 at 6:58
  • Can't install ngrok-client "E: Unable to locate package ngrok-client"
    – krismath
    Aug 12 '14 at 13:13
  • What Ubuntu version do you have? ngrok client is in universe repo in trusty: packages.ubuntu.com/trusty/ngrok-client
    – Shevchuk
    Aug 12 '14 at 13:57
0

While this is by no means the fastest or most advanced way to answer your question, I think it is probably the easiest to implement and understand.

The method I usually use is to set up a dummy e-mail account and poll it for new e-mails every second. This usually takes around 5-10 seconds from when you sent the e-mail on your phone and until the script runs. Note that you have to enable imap in the e-mail address you create.

Also make sure your bash script starts with the line:

#!/usr/bin/env bash

The python script I use is shown below. Of course you have to enter the relevant info in the first four all-caps variables. Open a text editor and save the following as email-run.py:

#!/usr/bin/env python

import imaplib,time,serial,subprocess

IMAP_SERVER = 'imap.gmail.com'
USERNAME = 'username'
PASSWORD = 'password'
PATH_TO_SCRIPT = '/root/Desktop/myscript.sh'
EXECUTE_IF_EMAIL_HAS = 'run'

def main():

    imap_conn = imaplib.IMAP4_SSL(IMAP_SERVER)
    imap_conn.login(USERNAME,PASSWORD)
    imap_conn.select()

    while(True):
        text = get_new_body(imap_conn)
        if text is not None:
            if EXECUTE_IF_EMAIL_HAS.lower() in text.lower():
                subprocess.call(PATH_TO_SCRIPT)
            imap_conn.store(1,'+FLAGS','\\Deleted')
            imap_conn.expunge()
        time.sleep(1)

def get_new_body(imap_conn):

    imap_conn.recent()
    (typ, data) = imap_conn.search(None, 'ALL')
    if data[0] == '':
        return None
    (typ, data) = imap_conn.fetch(1,'(RFC822)')
    msg = data[0][1].split('\r\n\r\n')

    index = 0
    while(True):
        if "text/plain" in msg[index]:
            break
        index += 1

    return msg[index+1]

if __name__ == "__main__":
    main()

You can run it with:

python email-run.py

2
  • If I understood this correctly, I could just let this program run and it will automatically run the script when an e-mail is received in the dummy e-mail, right?
    – krismath
    Aug 10 '14 at 2:04
  • Yes. You run the python script from a terminal on the laptop. It should then run the script you specify anytime an e-mail containing the specified EXECUTE_IF_EMAIL_HAS string (case insensitive) is received at the dummy address. Any e-mails received without that string will simply be deleted without running the script. This prevents it from activating on spam e-mails if you choose a good string. Note I modified the script to contain EXECUTE_IF_EMAIL_HAS. The original version I posted was an older one.
    – TheSchwa
    Aug 10 '14 at 3:31
0

Take a look at Pushbullet. From your smartphone, send a message (a "push") to your PC. A simple dbus listener runs on your PC and runs the script when the push is received. There is a Ubuntu AppIndicator that allows you to listen for pushes without a browser. See here.

2
  • Having skimmed through the site, I think there's no version for Linux, but there seems to be versions for Chrome and Firefox. How do I set up using those versions for chrome and Firefox, or is there a version for Linux? Thanks.
    – krismath
    Aug 10 '14 at 2:17
  • Added that to my answer.
    – Jos
    Aug 10 '14 at 5:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.