10

我对 python 脚本几乎是全新的,所以请原谅任何愚蠢的问题,但任何人都可以提供任何帮助将不胜感激。

我正在尝试编写一个 python 脚本供其他人使用,并且在其中我需要调用一个我并不总是知道路径的程序。为了解决这个问题,我要求用户提供程序的路径,这将起作用,但我不希望用户每次运行脚本时都必须提供路径,所以我一直在尝试设置一个 bash通过将脚本添加到 ~/.profile 和 ~/.bashrc 文件中来获得别名。

然后我可以使用别名从交互式 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

我做错了什么还是有另一种方法可以永久存储程序的路径?

4

5 回答 5

16

您想要的模块是subprocess

快速解决您的问题是使用 subprocess 模块,如下所示:

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

这相当于调用:

nuke -x scriptpath

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

但是,你应该非常小心,不要让自己接受任何 shell 注入(例如,如果从 CGI 页面调用此命令)

对于用户直接从 shell 调用的快速 scipts,他们可能不会比使用常规 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"])

*这可能不完全像这样工作,但你明白了

于 2011-07-28T10:10:49.043 回答
4

请注意,这os.system可能是使用sh而不是bash,因此source也会shopt失败。

如果它正在使用bash,它将失败,os.system因为每次调用都会创建一个新进程。你可以像这样在一行中做到这一点:

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

但是到目前为止.bashrc,您最好以其他方式获取路径(如果需要,甚至可以手动读取),然后使用subprocess.Popen().

于 2011-07-28T09:51:03.463 回答
3

我知道这是一个老问题,但是对于将来遇到这个问题的其他人来说,我认为值得一提的是,修改某人的 ~/.bashrc 或 ~/.profile 文件(尤其是默默地)是通常会失败的想法之一在“不良做法”的保护伞下。此外,对于您需要解决的问题,它似乎有点笨拙。

相反,为什么不让您的脚本跟踪存储在用户主目录中的自己的配置文件呢?ConfigParser使用,将您自己的 JSON 结构转储到文件中,或者如果您愿意,可以完全使用其他方式来执行此操作。

然后在您的脚本中,您可以首先检查它是否存在,如果存在,请查看它是否包含您要查找的保存可执行路径的密钥。如果其中任何一个测试失败,您知道您需要提示用户输入路径,此时您可以将其写入配置文件以备下次使用。

于 2014-08-29T19:07:58.133 回答
0

是的,不要那样做。将您的配置写入您自己的 dotfile,不要使用os.system,使用subprocess.

于 2011-07-28T09:15:17.290 回答
0

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

与其要求用户定义别名nuke,不如要求他们定义环境变量$NUKE。这使您免于弄乱.bashrc或任何其他配置文件。如果用户将其添加export NUKE=<path>到他们的.bashrc文件中,则在交互式执行 python 脚本时,它会自动在环境中可用。

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

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

于 2011-08-06T17:31:46.853 回答