Can I use an alias to execute a program from a python script

只愿长相守 提交于 2019-11-28 10:03:54

The module you want is subprocess.

A quick fix to your problem is to use the subprocess module, like so:

import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()

This is equivalent to calling:

nuke -x scriptpath

from the bash shell. The -i flag tells bash to behave as though it's an interactive session (and use the ~/.bashrc file)

BUT, you should be really really careful you're not opening yourself up to any shell injection (for instance, if this command is called from a CGI page)

For quick scipts that users invoke directly from the shell they probably can't do any more damage than they could with general shell access, but if this script is called by a web page a malicious user could pass something a bit like "rm -dfr ~/ &" as the program.*

If the number of executables is small, you might be better off either naming them in the script:

PROGRAMS = {"nuke": "/path/to/nuke"
                "foo" : "/path/to/foo" }

# Parse command line args
program = sys.argv[1] 

sp = subprocess.Popen([PROGRAMS[program], "other", "arguments", "to", "program"])

*This might not work exactly like this, but you get the idea

Be aware that os.system is probably using sh rather than bash, and so source and shopt will fail as well.

If it is using bash, it will fail as os.system creates a new process for each call. You could do it in one line like this:

os.system('source .bashrc; shopt -s expand_aliases; nuke -x scriptPath')

But you are by far best to get the path in some other way (or even read it from .bashrc manually if you want) and then use subprocess.Popen().

I know this is an old question, but for anyone else who comes across this in the future, I think it's worth mentioning that modifying someone's ~/.bashrc or ~/.profile files (especially silently) is one of those ideas that generally falls under the umbrella of "bad practice". Additionally, it seems a bit heavy-handed for the problem you need to solve.

Instead, why not have your script keep track of its own configuration file stored in the user's home directory? It would be quite simple to do this using ConfigParser, your own JSON structure dumped to a file, or something else entirely if you want.

Then in your script, you can first check if it exists, and if it does, see if it contains the key you're looking for that holds the executable path. If either of those tests fail, you know you need to prompt the user for the path, at which point you can write it to the config file for next time.

Yeah don't do that. Write your configuration out into your own dotfile, and don't use os.system, use subprocess.

I think an alias is a very complicated and not greatly intuitive way of using the shell environment. How about using environment variables instead? That's basically what they're for...

Instead of asking your users to define an alias nuke, ask them to define an environment variable $NUKE. This save you from messing with .bashrc or any other configuration file. If the user adds export NUKE=<path> to their .bashrc it is automatically available in the environment when executing the python script interactively.

If you only need this path to make a system call, just use os.system('$NUKE -x scriptPath').

If you need the value in python, it is easy to access as well: after import os, os.environ gives you a dictionary of all environment variables currently defined. Getting the value an alias is set to on the contrary is very cumbersome in python.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!