Python 如何用 shell 调用脚本中的函数+参数传递
【前言-给自己看的屁话】最近玩python 遇到了这个问题,在网上查了下,大部分博客文章都是讲的同一种方法,看起来一知半解的,所以觉得自己有必要整理一下。1、问题描述无论是在windows下也好,Linux下也好,都有shell,windows下是powershell,Linux下是bash等。windows下的python 可以有IDLE,Linux下的python一般没有(这是我目前的认知,仅
【前言-给自己看的屁话】
最近玩python 遇到了这个问题,在网上查了下,大部分博客文章都是讲的同一种方法,看起来一知半解的,所以觉得自己有必要整理一下。
1、问题描述
无论是在windows下也好,Linux下也好,都有shell,windows下是powershell,Linux下是bash等。windows下的python 可以有IDLE,Linux下的python一般没有(这是我目前的认知,仅供参考,如有不当,还望不吝赐教)。
有时候,我们想用自己以前在写的python 脚本里面的函数时,不想再打开之前的python脚本进行修改或是再创建个python脚本来调用之前python 脚本里面的函数,而是想直接通过shell来调用python 脚本里面的函数,并且可以向函数传递参数,毕竟大多数函数都是需要参数的。这,便是这种诉求!
如果可以这么干的话(肯定可以这么干,只不过写到这里的时候我还不会),那么我便可以干好多事情了。
2、在shell里跑python脚本
在shell中跑python 脚本很容易,先看一个简单的python脚本:
#!/usr/bin/python3
print("Hello, World!")
这个例子是从菜鸟里面摘抄的,关于第一行的理解,评论里有位大神这样写道:
关于实例中第一行代码#!/usr/bin/python3 的理解:
分成两种情况:
(1)如果调用python脚本时,使用:
python script.py
#!/usr/bin/python 被忽略,等同于注释。
(2)如果调用python脚本时,使用:
./script.py
#!/usr/bin/python 指定解释器的路径。
我很受启发。
下面在shell里面运行一下这个简单的脚本:
- powershell
注意到第二条命令,它并没有运行这个脚本,而是用默认应用程序(我的时npp)打开了这个脚本,所以没有返回值,整个界面和焦点都跳到了npp上 - bash
3、调用函数
这块参考:https://blog.csdn.net/xuezhangjun0121/article/details/91958296
这个我试了,没成:https://www.bbsmax.com/A/LPdoKwVjd3/
跟着第一个链接跑了个例子:
- St1:创建文件
port.py
并输入如下内容:
#!/usr/bin/python
# port.py
import socket
def scan(port):
s = socket.socket()
s.settimeout(0.1)
if s.connect_ex(('localhost', port)) == 0:
return 'port: ' + str(port) + ' open'
else:
return 'port: ' + str(port) + ' not open'
s.close()
if __name__ == '__main__':
scan()
- St2:逐条输入指令:
checkresult=`python -c 'import port; print port.scan(80)'`
echo $checkresult
python -c 'import port; print port.scan(80)'
下面我自己写个看看可不可以用
创建文件mine.py
并输入内容:
#!/usr/bin/python
def myfun(filepath,filename):
longfilename=filepath+'/'+filename
f=open(longfilename)
flist=f.readlines()
for line in flist:
print(line)
f.close()
if __name__ == "__main__":
myfun()
然后新建个文本文件a.txt
并输入如下内容(内容随便输入):
Hello world!
I am Bill O'Hanlon
I am learning Python
I am very happy!
Nice to meet you!
Good bye!
然后调用:
python -c 'import mine; mine.myfun(r"/home/ohanlon/Documents","a.txt")'
但是再powershell 里面就没成:
目前不知道原因,powershell看来和正常的shell还不一样。我的目的已经达到了,这个问题先放一放,以后再说。
4、通过sys模块向python脚本中传递参数
这个比较简单,下面看个例子即可。
#test.py
import sys
k = float(sys.argv[1])
y = sys.argv[2]
t = int(sys.argv[3])
print(k);print(type(k))
print(y);print(type(y))
print(t);print(type(t))
------------------
python .\test.py 2.3 sfansifjdnj 4 #python3 powershell
python test.py $g $q $s #python2 linux-bash
若想将脚本执行结果存储进shell变量中该怎么办呢?
a1=`python test.py $g $q $s`
若想用多个变量来存储python脚本执行结果该怎么办呢?
a1 a2 a3=`python test.py $g $q $s`
这样是不行的,我们可以将python脚本执行结果存到a1里面,这时候a1是个字符串:
4.76 <type 'float'> ndjknfkjs <type 'str'> 1 <type 'int'>
可以看到,它存储的就是上面print的内容,只不过用空格将每个print的内容隔开而已,若直接转化成array的话array=($a1)
,会将<type 'float'>
分成两部分的,因为它中间有个空格。这样的话,我们可以在输出上下点功夫:加;
,如下:
import sys
k = float(sys.argv[1])
y = sys.argv[2]
t = int(sys.argv[3])
print(k); print(';'); print(type(k)); print(';')
print(y); print(';'); print(type(y)); print(';')
print(t); print(';'); print(type(t))
这样,a1就变成了
4.76 ; <type 'float'> ; ndjknfkjs ; <type 'str'> ; 1 ; <type 'int'>
之后以;
为分隔符转化为字符数组:
array=(${a1//;/ })
本来以为这样就可以,但是还是不行,因为array=(str})
会默认以空格为分割符将字符串分割为数组的。那么就要先改变一下默认分割符再变回来了,操作如下:
OLD_IFS="$IFS"
IFS=";"
array=($a1)
IFS="$OLD_IFS"
echo ${#array[@]} #6
echo ${array[1]} #<type 'float'>
ok!
5、向python函数中传递shell中的变量
怎样可以实现将 shell 中的变量传递给 python 脚本中的函数呢?也就是说,我想用python脚本中的一个函数,但是是我懒得把这个函数从这个脚本中分离出来,而是想直接来用。
目前来看确实没有很好的解决方法,看来不可以偷懒了。
总结
python 脚本scrpit.py
一般可写为:
def function_name(param):
return reparam
if __name__ == "__main__":
function_name() #其实这两行可以不要。
调用:
python -c 'import script; print script.function_name(param)'
或者:
result=`python -c 'import script; print script.function_name(param)'`
echo $result
shell中的变量传递给python脚本
import sys
k = float(sys.argv[1])
y = sys.argv[2]
t = int(sys.argv[3])
-------------
python test.py $g $q $s #调用
python 脚本执行完之后将结果传出来(用print),多个变量的话,自选一个分割符,在多个变量之间加入print('分割符')
a1=`python test.py $g $q $s`
OLD_IFS="$IFS"
IFS=";"
array=($a1)
IFS="$OLD_IFS"
最后的结果会以字符数组的方式(一个变量一个索引)存在于array中。
更多推荐
所有评论(0)