1

I'm trying to call a self-defined command line function in python. I defined my function using apple script in /.bash_profile as follows:

function vpn-connect  {
/usr/bin/env osascript <<-EOF
tell application "System Events"
        tell current location of network preferences
                set VPN to service "YESVPN" -- your VPN name here
                if exists VPN then connect VPN
                repeat while (current configuration of VPN is not connected)
                    delay 1
                end repeat
        end tell
end tell
EOF
}

And when I tested $ vpn-connect in bash, vpn-connect works fine. My vpn connection is good.

So I created vpn.py which has following code:

import os

os.system("echo 'It is running.'")
os.system("vpn-connect")

I run it with python vpn.py and got the following output:

vpn Choushishi$ python vpn.py 
It is running.
sh: vpn-connect: command not found

This proves calling self-defined function is somehow different from calling the ones that's pre-defined by the system. I have looked into pydoc os but couldn't find useful information.

2
  • 1
    I suspect this has to do with the fact that os.system starts a subshell, and .bash_profile is not read for non-login shells, but I don't know why the existing function would not be visible in the subshell. Commented Apr 25, 2014 at 10:55
  • You might want to look at interfacing with AppleScript directly from Python, rather than using a shell script as an intermediary. Commented Apr 25, 2014 at 15:45

1 Answer 1

3
  1. A way would be to read the ./bash_profile before. As @anishsane pointed out you can do this:

    vpn=subprocess.Popen(["bash"],shell=True,stdin= subprocess.PIPE)
    vpn.communicate("source /Users/YOUR_USER_NAME/.bash_profile;vpn-connect")
    
  2. or with os.system

    os.system('bash -c "source /Users/YOUR_USER_NAME/.bash_profile;vpn-connect"')
    
  3. Or try

    import subprocess
    subprocess.call(['vpn-connect'], shell = True)
    
  4. and try

    import os
    os.system('bash -c vpn-connect')
    

    according to http://linux.die.net/man/1/bash

Sign up to request clarification or add additional context in comments.

2 Comments

os.system('bash -c "source /Users/YOUR_USER_NAME/.bash_profile;vpn-connect"') works. Thanks!
Another option would be to use vpn=subprocess.Popen(["bash"],shell=True,stdin= subprocess.PIPE);vpn.communicate("vpn-connect");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.