bash 我可以使用别名从 python 脚本执行程序吗

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6856119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:28:29  来源:igfitidea点击:

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

pythonbashunixaliasnuke

提问by Max

I am almost brand new to python scripting, so please excuse any stupid questions, but any help anyone can give would be much appreciated.

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

I am trying to write a python script for other people to use, and in it I need to call a program that I won't always know the path to. To get around that, I ask the user to provide the path to the program, which will work, but I don't want users to have to provide the path EVERY time they run the script so I have been trying to set up a bash alias by having the script add to the ~/.profile and ~/.bashrc files.

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

I can then use the alias to run the program from an interactive bash shell, but when the script tries to run it, I get a "command not found" error...

然后我可以使用别名从交互式 bash shell 运行程序,但是当脚本尝试运行它时,我收到“找不到命令”错误...

I have tried re-sourcing the .bashrc file and using the "shopt -s expand_aliases" command with no luck.

我尝试重新采购 .bashrc 文件并使用“shopt -s expand_aliases”命令但没有成功。

My ~/.bashrc looks like this:

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

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

And the piece of the script looks like this:

脚本部分如下所示:

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

But once the script gets up to this point, it returns:

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

sh: nuke: command not found

Am I doing something wrong or is there another way I can permanently store the path to a program?

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

回答by FredL

The module you want is subprocess.

你想要的模块是subprocess

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

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

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)

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

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)

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

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.*

对于用户直接从 shell 调用的快速脚本,他们可能无法造成比一般 shell 访问更多的损害,但是如果该脚本被网页调用,恶意用户可能会传递类似“rm -dfr”的内容~/ &" 作为程序。*

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

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

回答by Chris Morgan

Be aware that os.systemis probably using shrather than bash, and so sourceand shoptwill fail as well.

要知道,os.system大概是使用sh,而不是bash,所以sourceshopt也将失败。

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

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

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

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

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

回答by nrusch

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.

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

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.

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

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.

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

回答by zeekay

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

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

回答by kynan

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...

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

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

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

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

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

If you need the value in python, it is easy to access as well: after import os, os.environgives 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.

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