Python 如何用 shell 调用脚本中的函数+参数传递

【前言-给自己看的屁话】
最近玩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中。

猜你喜欢

转载自blog.csdn.net/Gou_Hailong/article/details/111091452