前言
在毕设中需要用到PHP
传递参数调用Python
脚本并获取后者返回的结果,经过查阅资料该问题得以解决。
思路
PHP
借助shell_exec
通过类似于python sum.py $aa $bb
的形式以执行系统命令的方式传递参数给Python
文件;
Python
则通过sys.argv
(需引入sys
模块)来接收命令中所包含的参数(需要注意的是:此时传入的参数都会被默认为str
类型,需要在函数内部进行解析和转换)并将处理结果通过print
函数输出;
PHP
通过将shell_exec
函数返回的结果赋给变量实现取得Python
返回数据的效果。
代码
PHP
:
<form action="" method="post">
请输入a:<input type="number" name="a" value="请输入a"><br> 请输入b:
<input type="number" name="b" value="请输入b">
<button type="submit">计算</button>
</form>
<?php
$aa = $_POST["a"];
$bb = $_POST["b"];
$cmd = shell_exec("python sum.py $aa $bb");
echo "a与b的和是: $cmd";
?>
Python
:
import sys
a, b = sys.argv[1], sys.argv[2] # 接收位置参数
print(int(a)+int(b))
效果
补充
Python
:
除了sys.argv
,Python
还可以通过argparse
、tf.app.run
获取传入参数。
相对于sys.argv
,argparse
和tf.app.run
可以认为是基于参数名称的传入
(前者是基于位置的参数传入
)。
后者的具体使用方法记录如下:
argparse
示例1:
import argparse
parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument('--gpus', type=str, default = None)
parser.add_argument('--batch-size', type=int, default=32)
args = parser.parse_args()
print args.gpus
print args.batch_size
利用argparse
模块,在函数内定义好相关的命名参数(包括名称、数据类型和默认值等),从而在命令行中可以方便的调用。
需要注意的是,脚本运行命令python script.py -gpus=0,1,2 --batch-size=10
中的--batch-size
会被自动解析成batch_size
.parser.add_argument
方法的type
参数理论上可以是任何合法的类型, 但有些参数传入格式比较麻烦,例如list
,所以一般使用bool
, int
, str
, float
这些基本类型就行了,更复杂的需求可以通过str
传入,然后手动解析。bool
类型的解析比较特殊,传入任何值都会被解析成True
,传入空值时才为False
python script.py --bool-val=0 # args.bool_val=True
python script.py --bool-val=False # args.bool_val=True
python script.py --bool-val= # args.bool_val=什么都不写False
示例2:
Python
:
import argparse
parser = argparse.ArgumentParser(description='a demo of script')
parser.add_argument('--a', type=float, default=0.0) # 添加变量
parser.add_argument('--b', type=float, default=1.0)
if __name__ == '__main__':
args = parser.parse_args() # 解析所有的命令行传入变量
add(args.a, args.b)
Shell
:
python script.py --a=4.0 --b=3.0
# 另一种写法: python script.py --a 4.0 --b 3.0
# 返回结果7.0
总结:通过这个方法还能指定命令的帮助信息。具体请看API
文档:https://docs.python.org/2/library/argparse.html
通过这个方法还能指定命令的帮助信息。具体请看API
文档:https://docs.python.org/2/library/argparse.html
tf.app.run
tensorflow
也提供了一种方便的解析方式。
脚本的执行命令为:
python script.py -gpus=0,1,2 --batch_size=10
对应的python代码为:
import tensorflow as tf
tf.app.flags.DEFINE_string('gpus', None, 'gpus to use')
tf.app.flags.DEFINE_integer('batch_size', 5, 'batch size')
FLAGS = tf.app.flags.FLAGS
def main(_):
print FLAGS.gpus
print FLAGS.batch_size
if __name__=="__main__":
tf.app.run()
有几点需要注意:
tensorflow
只提供以下几种方法:
tf.app.flags.DEFINE_string
,
tf.app.flags.DEFINE_integer
,
tf.app.flags.DEFINE_boolean
,
tf.app.flags.DEFINE_float
四种方法,分别对应str
, int
,bool
,float
类型的参数。这里对bool
的解析比较严格,传入1
会被解析成True
,其余任何值都会被解析成False
。
脚本中需要定义一个接收一个参数的main
方法:def main(_):
,这个传入的参数是脚本名,一般用不到, 所以用下划线接收。
以batch_size
参数为例,传入这个参数时使用的名称为--batch_size
,也就是说,中划线不会像在argparse
中一样被解析成下划线。
tf.app.run()
会寻找并执行入口脚本的main
方法。也只有在执行了tf.app.run()
之后才能从FLAGS
中取出参数。
从它的签名来看,它也是可以自己指定需要执行的方法的,不一定非得叫main
:
run(
main=None,
argv=None
)
tf.app.flags
只是对argpars
的简单封装。代码见https://github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/python/platform/flags.py
PHP
:
除了使用shell_exec()
,还可以使用exec()
、passthru()
和system()
函数调用系统命令,
它们四者的区别如下:
shell_exec()
通过
shell
环境执行命令,并且将完整的输出以字符串的方式返回。
也就是说,PHP
先运行一个shell
环境, 然后让shell
进程运行你的命令, 并且把所有输出以字符串形式返回, 如果程序执行有错误或者程序没有任何输出, 则返回null
.
exec()
string exec ( string $command [, array &$output [, int &$return_var ]] )
与shell_exec()
不一样,exec
不会创建shell
进程, 可以理解是php
进程直接创建一个子进程, 运行指定的命令, 返回值只返回命令的最后一行, 所有的返回以参数形式返回, 上面的$output
, 进程的退出代码以另外一个参数变量返回, 上面的$return_var
passthru()
void passthru ( string $command [, int &$return_var ] )
与exec()
类似, 唯一不同的是, 命令的所有输出返回内容都不再导入到PHP
环境, 而是直接作为输出内容, 返回到浏览器的输出上, 等效是把所有返回内容直接echo
输出.
system()
这个方法和
passthru()
类似, 但是system()
方法会在程序的每行输出的时候执行一次缓存输出动作, 可以理解为, 只要外部程序输出一行,php
就会马上把内容推送到浏览器, 无论这个内容是否足够大.php
通常为了输出效率, 都会有一个输出缓存, 会等到输出内容足够大之后, 再一次输出返回.system()
方法则强制输出内容立刻推送, 即使输出的内容只有一个字母. 如果客户端具有实时打印服务器的返回http
内容流的能力, 就可以看到system()
的实时推送效果.
参考资料:
https://www.cnblogs.com/chenbjin/p/4060590.html
https://blog.csdn.net/weixin_35653315/article/details/72886718
https://blog.csdn.net/guofei_fly/article/details/104577019
https://www.zhihu.com/question/47622493
https://segmentfault.com/q/1010000010717254
https://www.cnblogs.com/aland-1415/p/6613449.html
版权属于:soarli
本文链接:https://blog.soarli.top/archives/605.html
转载时须注明出处及本声明。
期待你的远程命令执行
大佬牛逼,之前心心念念的功能你直接帮俺解决啦.
大佬牛逼,之前心心念念的功能你直接帮俺解决啦
文章写得不错,支持一下!