dzh*_*lil 13 python bash shell
有很多关于如何从python运行shell命令的文献,但我感兴趣的是反过来.我有一个python模块mycommands.py,其中包含如下所示的函数
def command(arg1, arg2):
pass
def command1(arg1, arg2, arg3):
pass
Run Code Online (Sandbox Code Playgroud)
其中函数参数都是字符串.目标是能够从下面的bash运行这些函数
$ command arg1 arg2
$ command1 arg1 arg2 arg3
Run Code Online (Sandbox Code Playgroud)
到目前为止,我在.bash_profile中有以下粗暴设置,我必须手动为每个python函数提供bash绑定
function command() {
python -c "import mycommand as m; out=m.command('$1', '$2'); print(out)"
}
function command1() {
python -c "import mycommand as m; out=m.command1('$1', '$2', '$3'); print(out)"
}
Run Code Online (Sandbox Code Playgroud)
如果一个人可以拥有一个bash命令就好了
$ import_python mycommands.py
Run Code Online (Sandbox Code Playgroud)
它将自动导入模块中的所有python函数作为bash命令.是否存在实现此类命令的库?
您可以创建一个基本脚本,让我们说command.py一下这个脚本被调用的名称(不要忘记让它可执行):
#!/usr/bin/python
import os.path
import sys
def command1(*args):
print 'Command1'
print args
def command2(*args):
print 'Command2'
print args
commands = {
'command1': command1,
'command2': command2
}
if __name__ == '__main__':
command = os.path.basename(sys.argv[0])
if command in commands:
commands[command](*sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建此脚本的软链接:
ln -s command.py command1
ln -s command.py command2
Run Code Online (Sandbox Code Playgroud)
最后测试一下:
$ ./command1 hello
Command1
('hello',)
$ ./command2 world
Command2
('world',)
Run Code Online (Sandbox Code Playgroud)
小智 5
根据您的实际使用情况,最佳解决方案可能是简单地使用Click(或至少argparse标准库中的模块)来构建您的Python脚本并将其称为
command sub-command arg1 args2
Run Code Online (Sandbox Code Playgroud)
从壳.
请参阅Mercurial,了解其中一个突出的例子.
如果您确实必须将命令作为第一级shell命令,请使用符号链接或别名,如其他答案中所述.
只需几个方法,您可以进行符号链接和调度sys.argv[0]:
$ cat cmd.py
#!/usr/bin/env python
if __name__ == '__main__':
import sys
from os.path import basename
cmd = basename(sys.argv[0])
print("This script was called as " + cmd)
$ ln -s cmd.py bar
$ ln -s cmd.py foo
$ ./foo
This script was called as foo
$ ./bar
This script was called as bar
Run Code Online (Sandbox Code Playgroud)
使用多个子命令,您可以在Python脚本中添加以下内容以"自动化"该过程:
#!/usr/bin/env python
import sys
def do_repeat(a, b):
print(a*int(b))
def do_uppercase(args):
print(''.join(args).upper())
def do_eval():
print("alias repeat='python cmd.py repeat';")
print("alias uppercase='python cmd.py uppercase';")
if __name__ == '__main__':
cmd = sys.argv[1]
if cmd=='--eval':
do_eval()
else:
args = sys.argv[2:]
if cmd=='repeat':
do_repeat(*args)
elif cmd=='uppercase':
do_uppercase(args)
else:
print('Unknown command: ' + cmd)
Run Code Online (Sandbox Code Playgroud)
你会像这样使用它(假设cmd.py你的某个地方有一个可执行的Python脚本$PATH):
$ cmd.py --eval # just to show what the output looks like
alias repeat='python cmd.py repeat';
alias uppercase='python cmd.py uppercase';
$ eval $(python cmd.py --eval) # this would go in your .bashrc
$ repeat asdf 3
asdfasdfasdf
$ uppercase qwer
QWER
Run Code Online (Sandbox Code Playgroud)
注意:上面是一个非常基本的例子,展示了如何eval在shell中使用.