6

I'm trying to run a system call from Python. I have a line that reads this in my Python script:

return os.system("crux tide-index")

crux is a program existing in my /home/ directory, and if I type the command crux tide-index into a terminal, it seems to work properly.

When I run my Python script, it reaches the line above and then outputs this line to stderr (i.e. it shows up in the output of my terminal):

sh: 1: crux not found

I don't understand why I can run the command in my terminal, but not in a Python script. Is there something I'm missing? Is the fact that crux is in my /home/ folder possibly the problem?

5
  • have you tried calling return os.system("/home/crux tide-index") ? Commented Mar 8, 2017 at 16:47
  • Alternatively, you can add it to your PATH, then call it from anywhere. Commented Mar 8, 2017 at 16:48
  • Normally, crux tide-index won't actually work for something in your home directory, unless you've added your home directory to your PATH, or have an alias or shell function wrapping it. The alias approach seems likely -- a PATH update will be inherited by subprocesses (including Python), but an alias or non-exported shell function won't. Commented Mar 8, 2017 at 16:53
  • BTW, inasmuch as * has actual literal meaning to a shell, putting it in your question title was a bit unclear. Commented Mar 8, 2017 at 16:54
  • What's the output of running type crux in your terminal? Commented Mar 8, 2017 at 16:55

3 Answers 3

7

Possible Reasons

There are several reasons you could be able to run this in your terminal, but not in a Python script.

  • It could be defined as an alias.

    If you have alias crux=~/crux in your .bashrc or similar, that would explain the issue.

  • It could be defined as a function.

    crux() { ~/crux "$@"; } is an example of a shell function that starts the crux executable. However, like any other function, this is local to the shell wherein it's defined. (Bash has "exported functions", but these aren't available in POSIX sh, and you need to go out of your way to use them anyhow).

  • You could have a different PATH between your interactive CLI and your script.

    If you have PATH=$PATH:$HOME somewhere in your shell's dotfiles, this will add your home directory to the location searched for new executables. On its own, this will be exported to subprocesses, so searched by the /bin/sh instance started by os.system() in Python -- but if your script is being started by cron or another service, it wouldn't have that PATH update.

Debugging

Run type crux in your interactive shell. Output will be of the form of one of the following:

  • crux is aliased to `/home/kestrel/crux' means that it works in your interactive shell only due to an alias. Update your PATH to include /home/kestrel, or modify your Python script to fully-qualify the script's location.
  • ...or if you get:

    crux is a function
    crux ()
    {
        /home/kestrel/crux "$@"
    }
    

    ...it means exactly what it says: crux is a function that in turn invokes /home/kestrel/crux. You can then put /home/kestrel/crux directly in your Python script.

  • ...or if you get either of:

    crux is hashed (/home/kestrel/crux)
    

    or

    crux is /home/kestrel/crux
    

    then crux is directly in the PATH for your interactive command prompt, but not for your Python script. Edit the PATH associated with your script appropriately.

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

Comments

2

This was because PyCharm's os.system did not load bashrc's env variable values unless you start your Pycharm in your terminal and not quit. So you should manually try the command below in your terminal to get the absolute path of crux: whereis crux then use absolute path of crux instead of crux in your PyCharm.

Comments

1

this error caused by the confusing path to the executable file. so you can fix this erro through pointing th explicit path to the executable file. like this:

>>> a = os.popen("TMscore ./download/pdbs/1ACF.pdb ./download/pdbs/1ACF.pdb")
>>> /bin/sh: 1: TMscore: not found  
>>> a = os.popen("~/bins/TMscore ./download/pdbs/1ACF.pdb ./download/pdbs/1ACF.pdb").readlines()
>>> a 
['\n', ' *************************************************************************\n', ' *        
                     TM-SCORE                              *\n', ' * A scoring function to ass

ess the similarity of protein structures *\n', ' * Based on statistics:

Comments

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.