在Linux系統當中,有時Shell腳本的功能並不能完全滿足我們的需求,尤其是遇到一些循環和數值計算,以及一些交互功能的實,這時,Python的優勢就十分明顯了。
本人今天稍微整理了以下關於Python+Shell混合編程的一些方法和應用到的一些模塊,並通過Shell+Python設計了一個針對VASP的交互腳本,供大家參考。
#!bin/sh
echo "hello shell"
#下面是調用python解釋器
/usr/bin/python<<-EOF
print('hello python')
EOF輸出結果:
hello this is shell
hello this is python(1)如果調用python腳本時,使用:python ***.py #!/usr/bin/python 被忽略,等同於注釋。(2)如果調用python腳本時,使用:./***.py #!/usr/bin/python 指定解釋器的路徑。
向python函數中傳遞shell變量
此時在python腳本中需要引入sys模塊,從而調用外部參數。
這裡還是在shell腳本中引入python
#!bin/sh
echo "hello shell"
i=0.05;j=1.2;k=4
#寫入python腳本
cat > test.py <<EOF
import sys
i= float(sys.argv[1])
j=float(sys.argv[2])
k=int(sys.argy[3])
print("the number is {}".format(i+j+k) )
EOF
#引用shell腳本參數並調用python函數
python test.py $i $j $k輸出結果:
hello shell
the number is 5.25
利用os.system() 直接執行系統操作,並列印在屏幕上import os
os.system('ls')利用os.popen()
執行作業系統的命令,會將結果保存在內存當中,可以用read()方法讀取出來
res = os.popen('ls -l')
print res
#or
print res.read()import subprocess
# python 解析則傳入命令的每個參數的列表
subprocess.run(["df","-h"])
# 需要交給Linux shell自己解析,則:傳入命令字符串,shell=True
subprocess.run("df -h|grep /dev/sda1",shell=True)- subprocess.call()
執行命令,返回命令的結果和執行狀態,0或者非0res = subprocess.call(["ls","-l"])
res
#輸出0或者非0- subprocess.check_call()
執行命令,返回結果和狀態,正常為0 ,執行錯誤則拋出異常.語法同上
- subprocess.getstatusoutput()
接受字符串形式的命令,返回 一個元組形式的結果,第一個元素是命令執行狀態,第二個為執行結果res = subprocess.getstatusoutput('pwd')- subprocess.getoutput()#!/share/home/wanjg/WSY/software/Anaconda/bin/python3
2 import subprocess
3 def fun(command):
4 ret = subprocess.getoutput(command)
5 print(ret)
7 fun('ls -a')
接受字符串形式的命令,返回執行結果。
- subprocess.check_output()
執行命令,返回執行的結果,而不是列印(以字節形式返回)實例:以下是我根據上述shell+Python混合編程的方法,簡單實現了對VASP進行縮放係數優化的腳本,主要利用了Python的subprocess模塊進行實現。
#!/share/home/wanjg/WSY/software/Anaconda/bin/python3
import os
import subprocess
import numpy as np
filepath=os.getcwd()
#選擇功能
fun = int(input("Set scaling factor\n1.Calculation\n2.Get Energy\n"))
if fun==1:
#選擇縮放係數的範圍和步長
Min=float(input('Please enter the minmum scaling factor:\n'))
Max=float(input('Please enter the maximum scaling factor:\n'))
step=float(input("Please input the step:\n"))
fp=open('file-name','w+')
for items in np.arange(Min,Max+step,step):
filename=str(float('%.3f' % items))
fp.write(filename+'\n')
os.mkdir(filename)
os.chdir(filepath+'//'+filename)
subprocess.call('cp ../INCAR ../POSCAR ../KPOINTS ../POTCAR ./',shell=True)
commands="sed -n 2c"+filename+" POSCAR"
#print(commands)
subprocess.run(commands,shell=True)
#運行VASP,可根據自己伺服器修改
run="source ~/.bashrc"+";"+"wsy_vasp"+" "+filename+" 24"
subprocess.call(run,shell=True)
os.chdir(filepath)
pass
fp.close()
if fun==2:
#將各個體系的能量數據寫入Energy.dat
filename=open("file-name",'r')
data=open('Energy.dat','w')
#讀取能量數據操作
commands="grep TOTEN OUTCAR|tail -1|awk '{printf \"%12.6f\", $5}'"
#讀取並寫入能量數據
for items in filename.readlines():
i= items.split()[0]
os.chdir(filepath+'//'+i)
ret=subprocess.getoutput(commands)
os.chdir(filepath)
data.write(ret+'\n')