我可以使用别名在Python脚本中执行程序吗?

10

我对Python脚本几乎一无所知,所以请原谅任何愚蠢的问题,但如果有人能提供帮助,我将不胜感激。

我正在尝试编写一个Python脚本,供他人使用,在其中需要调用一个我不总是知道路径的程序。为了解决这个问题,我要求用户提供程序的路径,这样可以工作,但我不想让用户每次运行脚本时都必须提供路径,因此我一直在尝试通过让脚本添加到~/.profile和~/.bashrc文件来设置Bash别名。

然后我可以使用该别名从交互式Bash shell运行程序,但脚本尝试运行它时,会出现“命令未找到”错误...

我已经尝试重新加载.bashrc文件并使用“shopt -s expand_aliases”命令了,但没有成功。

我的~/.bashrc文件看起来像这样:

alias nuke='/Applications/Nuke6.2v4/Nuke6.2v4.app/Contents/MacOS/Nuke6.2v4'

脚本的这部分代码如下所示:

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

但是一旦脚本运行到这个点,它就会返回:

sh: nuke: command not found

我是否做错了什么或者有没有其它方法可以永久性地存储程序的路径?


1
请注意,您需要在不同的进程中运行这三个命令。前两个命令只会影响当前正在运行的 shell,因此当您执行第三个命令时,.bashrc 文件将不会被加载,shopt 也不会被设置。 - Joachim Sauer
5个回答

17

你需要的模块是subprocess

快速解决问题的方法是使用subprocess模块,像这样:

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

这等同于调用以下代码:

nuke -x scriptpath

使用bash shell。-i标志告诉bash表现得像一个交互式会话(并使用~/.bashrc文件)

但是,你应该非常小心,不要让自己暴露在任何shell注入的风险中(例如,如果这个命令从CGI页面调用)

对于用户直接从shell调用的快速脚本,他们可能无法造成比一般shell访问更多的破坏,但是如果这个脚本被网页调用,恶意用户就可以将像“rm -dfr ~/ &”这样的东西传递给程序。

如果可执行文件的数量很少,你最好在脚本中命名它们:

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"])

*这可能不会完全像这样工作,但你可以理解其中的意思


2
在第一个Popen示例中,它不应该是这样的吗:subprocess.Popen(["/ bin / bash","-i","-c","nuke -x scriptpath"])--即“-c”选项的单个参数。 - glenn jackman

4
请注意,os.system 可能使用的是 sh 而不是 bash,因此 sourceshopt 也将失败。
如果它确实使用的是 bash,由于 os.system 在每次调用时都会创建一个新进程,所以它也会失败。您可以像以下一行代码这样完成它:
os.system('source .bashrc; shopt -s expand_aliases; nuke -x scriptPath')

但是最好通过其他方式(甚至手动从.bashrc中读取)获取路径,然后使用subprocess.Popen()


3
我知道这是一个老问题,但对于未来遇到此类问题的任何人来说,我认为值得一提的是,修改某人的 ~/.bashrc 或 ~/.profile 文件(尤其是悄悄地)通常属于“不良实践”范畴。此外,这似乎有点过度,不必要地解决你需要解决的问题。
相反,为什么不让你的脚本跟踪它自己在用户主目录中存储的配置文件呢?使用 ConfigParser、自己的 JSON 结构转储到文件中或其他完全不同的方式都可以很容易地完成这个任务。
然后,在你的脚本中,你可以首先检查它是否存在,如果存在,则查看它是否包含你正在寻找的保存可执行路径的键。如果其中任何一个测试失败,你就知道需要提示用户输入路径,此时你可以将其写入配置文件以备下次使用。

0

我认为别名是一种非常复杂且不太直观的使用 shell 环境的方式。那么,使用环境变量怎么样呢?这基本上就是它们的用途...

与其要求用户定义别名 nuke,不如要求他们定义环境变量 $NUKE。这样可以避免对 .bashrc 或任何其他配置文件进行操作。如果用户将 export NUKE=<path> 添加到他们的 .bashrc 中,则在交互式执行 python 脚本时,该变量会自动出现在环境中。

如果您只需要此路径来进行系统调用,只需使用 os.system('$NUKE -x scriptPath')

如果您需要在 python 中访问该值,也很容易:在 import os 后,os.environ 会给您提供当前定义的所有环境变量的字典。相反,获取别名设置的值在 python 中非常麻烦。


0

是的,不要这样做。将您的配置写入自己的点文件中,而不使用os.system,使用subprocess


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接