我几乎是全新的python脚本,所以请原谅任何愚蠢的问题,但任何人可以给任何帮助将不胜感激。
我正在尝试编写一个python脚本供其他人使用,并且在这个脚本中我需要调用一个我不会总是知道path的程序。 为了解决这个问题,我要求用户提供程序的path,这将工作,但我不希望用户必须提供path每次他们运行的脚本,所以我一直试图build立一个bash别名通过脚本添加到〜/ .profile和〜/ .bashrc文件。
然后,我可以使用别名从交互式bash shell运行程序,但是当脚本尝试运行它时,出现“command not found”错误…
我尝试重新采购.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
我做错了什么,或者有另一种方式,我可以永久存储path的程序?
你想要的模块是子进程 。
快速解决您的问题是使用子流程模块,如下所示:
import subprocess sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"]) sp.communicate()
这相当于调用:
nuke -x scriptpath
从bash外壳。 -i标志告诉bash表现得好像是一个交互式会话(并使用〜/ .bashrc文件)
但是,你应该非常小心,你不打开任何shell注入(例如,如果这个命令是从CGI页面调用的)
对于用户直接从shell调用的快速scip文件,它们可能不会比通常的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"])
*这可能不会像这样,但你明白了
请注意, os.system
可能使用sh
而不是bash
,所以source
和shopt
也会失败。
如果使用bash
,则会因为os.system
为每个调用创建一个新进程而失败。 你可以这样做:
os.system('source .bashrc; shopt -s expand_aliases; nuke -x scriptPath')
但是最好还是以其他方式获取路径(甚至可以手动从.bashrc
读取),然后使用subprocess.Popen()
。
我知道这是一个古老的问题,但对于将来碰到这个问题的其他人,我认为值得一提的是,修改某人的〜/ .bashrc或〜/ .profile文件(特别是默默地)在“坏习惯”的保护下。 另外,你需要解决的问题似乎有点过分。
相反,为什么不让脚本跟踪存储在用户主目录中的配置文件呢? 使用ConfigParser
,自己的JSON结构转储到一个文件,或者其他的东西,如果你想的话,这将是非常简单的。
然后在你的脚本中,你可以先检查它是否存在,如果存在,看它是否包含你正在寻找的可执行文件路径。 如果其中一个测试失败,则需要提示用户输入路径,此时可以将其写入配置文件中。
是的,不要那样做。 将你的配置写入你自己的dotfile,不要使用os.system
,使用subprocess
os.system
。
我认为一个别名是一个非常复杂的,而不是非常直观的使用shell环境的方式。 如何使用环境变量呢? 这基本上是他们的…
而不是要求你的用户定义一个别名nuke
,要求他们定义一个环境变量$NUKE
。 这节省了您与.bashrc
或任何其他配置文件的麻烦。 如果用户将export NUKE=<path>
到它们的.bashrc
,则在交互式执行python脚本时,它将在环境中自动可用。
如果你只需要这个路径来进行系统调用,只需使用os.system('$NUKE -x scriptPath')
。
如果你需要python中的值,也很容易访问:在import os
, os.environ
给你一个当前定义的所有环境变量的字典。 获取值别名被设置为相反是非常繁琐的python。