A. linux下python怎麼用vscode設定yapf
為VSCode安裝擴展
用VSCode編程是需要依賴擴展的。寫Python需要安裝python的擴展,寫C++需要安裝C++的擴展。剛打開編輯器的時候,它一般會推薦一些擴展,你如果什麼都不知道,可以先安裝官方推薦的這些擴展:
修改VSCode的一些選項的默認值
VSCode有很多選項可以被修改,其各個選項都有默認值,這些默認值存儲在"\settings.json"中(不過我沒找到這個文件),用戶如果想修改某些選項的值(比如:修改字體的大小),VSCode會自動幫我們生成一個「settings.json」文件,然後我們直接在這個文件中配置自己想要的值即可。
VSCode還沒有創建"settings.json"文件:
VSCode幫我們創建了"settings.json"文件:
我們修改字型大小,讓字體大一些。修改完後,保存一下,自定義的值就會覆蓋默認值,修改就生效了。
用VSCode編寫和調試python程序
下面就開始用VSCode編程了。因為python的配置超簡單,我們以python為例來說明一下。
https //segmentfault com/q/1010000005897116
VSCode是以文件夾作為項目單位的。所以,我們如果要新建一個python項目的話,需要新建一個文件夾,然後在這個文件夾裡面放置.py文件。然後讓VSCode"打開文件夾",這樣VSCode就能識別這個項目了。(當然可以用VSCode直接創建文件夾和文件。)
先創建test_python文件夾,裡面創建一個test.py文件。
然後用VSCode載入它:
載入後的樣子。可以看到,因為安裝了python擴展,已經有高亮等效果了。
下面開始調試。
很顯然要選擇python選項:
然後VSCode為我們自動生成了"launch.json"文件,此文件有很多配置項,有的選項是默認從"settings.json"中取值的(比如"config.python.pythonPath")。如果"settings.json"中沒有配置它們的話,調試時可能會無法啟動。
同時,項目文件夾下面還自動生成了".vscode"文件夾。文件"launch.json"就在這個文件夾中。此時VSCode才算是真正意義上接手了這個項目文件夾。
網上的教程里,直接先在"settings.json"中把"python.pythonPath"先配置了一下,我當時不是太理解。現在看來,我們也需要配置一下了。
配置完之後,就可以正常調試程序了。
用VSCode調試帶參的Python程序
修改test.py裡面的代碼,讓它能列印參數(修改後的代碼見下面的圖片)。
修改launch.json,找到"configurations"中"name"為"Python"的那個配置塊,給它添加"args"項,如下圖所示:
添加前的配置塊:
添加後的配置塊:
文件launch.json修改完畢後,按F5調試程序,可以看到控制台輸出的結果:
在按F5調試時,VSCode每次都會在程序入口處暫停住,這是配置項"stopOnEntry"在起作用,將其改成false後就不會出現這種情況了。
用VSCode自動格式化代碼
VSCode「自動格式化代碼」的快捷鍵是「Alt+Shift+F」。要格式化Python代碼,需要安裝Python包yapf(或autopep8、等)。
在命令行下執行:
[plain] view plain
python -m pip install yapf
然後配置"settings.json",啟用yapf:
用VSCode對python代碼進行語言分析
VSCode使用python的語言分析(寫python代碼的時候,編輯器會提示哪裡出錯,哪裡的代碼格式不規范),可以安裝flake8(或pylint、等):
在命令行下執行:
[plain] view plain
python -m pip install flake8
然後配置"settings.json",啟用flake8:
更換文件圖標主題(使VSCode左側的資源管理器根據文件類型顯示圖標):
可以選擇已經存在的文件圖標主題:"文件"->"首選項"->"文件圖標主題"->"Seti(Visual Studio Code)"。
你也可以安裝「vscode-icons」插件,安裝的方式:
在「擴展(Ctrl+Shift+X)」中,搜索「vscode-icons」,然後安裝並重新載入它,然後VSCode會讓你執行一些操作,以激活"vscode-icons"插件。操作為:
"文件"->"首選項"->"文件圖標主題"->"VSCode Icons"。對應到英文的話,應該是"File" -> "Preferences" -> "File Icon Theme"->"VSCode Icons"。
Guides(縮進線插件,讓代碼看起來更清晰):
在「擴展(Ctrl+Shift+X)」中,搜索「Guides」,然後安裝並重新載入它即可。
B. linux如何編寫python腳本
在Linux環境下編寫python腳本
相關推薦:《Python教程》
1、首先定位到一個文件夾,然後使用vim編輯器:vim test.py 就創建了python腳本文件,並且進入編輯狀態。
2、編輯好之後按Esc鍵切換到命令模式,然後輸入:wq,按回車鍵就自動保存完成了,然後輸入python test.py,即可運行程序(前提是linux環境裝好python)。
C. 如何編譯可以在Windows下運行的帶有Python支持的ARM Linux GDB
做這件事情的目的是為了在QtCreator里調試ARM Linux程序的時候,能看清楚QString、QList這些Qt特有的對象的內容,而不是一個完全看不懂的結構體。
目前(2014年8月)Linaro、CodeSourcery的GCC工具鏈里的GDB都不支持Python。想知道你用的GDB支持不支持,試一試就行,這樣表示不支持:
(gdb) python
>print 'Hello GDB!'
>(按Ctrl+D)Python scripting is not supported in this of GDB.
這樣表示支持:
(gdb) python
>print 'Hello GDB!'
>(按Ctrl+D)Hello GDB!
這件事情乍一看也很簡單,只要把GDB源碼下載下來,然後再配置,打開Python支持就行了。實際上會遇到的問題是,在MinGW下,又要與「\」和「:」這兩個Windows路徑里的刺頭斗爭了。我覺得我之前挺傻,編譯MinGW下Qt的時候,就去硬磕源碼和configure腳本去了。這次GDB的configure是自動生成的,不是給人看的,configure.ac看起來也很費勁,根本磕不下去,於是我換了個思路,在ubuntu下交叉編譯吧,sudo apt-get install mingw32,這是Ubuntu下的MinGW交叉編譯器。
然後是依賴,這樣的GDB要依賴expat和python的開發版本。如果是ubuntu底下直接編譯,apt-cache search一下他們的開發版本,然後sudo apt-get install一下就好了;給MinGW交叉編譯就麻煩了。先說expat,這個好辦,把http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz下載下來,然後:
./configure --prefix=[安裝目錄,如/home/c/mingw-gdb/expat] --host=i586-mingw32msvc
make
make install
會提示一些警告,無視即可。
Python就無語了,目前的GDB貌似最高支持Python 2.7,而2.7版本的Python本身不支持MinGW…… 好在有高手做了Patch,也寫了說明,可以參考這文章:http://mdqinc.com/blog/2011/10/cross-compiling-python-for-windows-with-mingw32/
但是,就算這樣,編譯也充滿挑戰,要修復很多問題,出來的Python還少「nt」模塊。就在我覺得沒辦法的時候,突然發現Windows版Qt提供的MinGW居然內置了Python開發包,位置在Tools/mingw48_32/opt,趕緊把它拷貝到Linux下,比如/home/c/mingw-gdb/python。當然,你也必須確保ubuntu下有可用的python。
然後,給GDB打一個補丁:
--- gdb-7.8/gdb/configure 2014-07-29 20:37:42.000000000 +0800
+++ gdb-7.8-old/gdb/configure 2014-08-30 00:08:27.122042706 +0800
@@ -8263,21 +8263,22 @@
# We have a python program to use, but it may be too old.
# Don't flag an error for --with-python=auto (the default).
have_python_config=yes
- python_includes=`${python_prog} ${srcdir}/python/python-config.py --includes`
+ python_config_tool=`echo ${python_prog} | sed "s#python.exe#python-config#g"`
+ python_includes=`${python_config_tool} --includes`
if test $? != 0; then
have_python_config=failed
if test "${with_python}" != auto; then
as_fn_error "failure running python-config --includes" "$LINENO" 5
fi
fi
- python_libs=`${python_prog} ${srcdir}/python/python-config.py --ldflags`
+ python_libs=`${python_config_tool} --ldflags`
if test $? != 0; then
have_python_config=failed
if test "${with_python}" != auto; then
as_fn_error "failure running python-config --ldflags" "$LINENO" 5
fi
fi
- python_prefix=`${python_prog} ${srcdir}/python/python-config.py --exec-prefix`
+ python_prefix=`${python_config_tool} --exec-prefix`
if test $? != 0; then
have_python_config=failed
if test "${with_python}" != auto; then
@@ -8343,12 +8344,12 @@
return 0;
}
_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+#if ac_fn_c_try_link "$LINENO"; then :
have_libpython=${version}
found_usable_python=yes
PYTHON_CPPFLAGS=$new_CPPFLAGS
PYTHON_LIBS=$new_LIBS
-fi
+#fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CPPFLAGS=$save_CPPFLAGS
這個補丁的目的是強制為檢測到python。
然後給拷貝到Linux下的python開發包打一個補丁:
--- python-old/bin/python-config 2013-04-18 02:43:01.000000000 +0800
+++ python/bin/python-config 2014-08-30 00:53:16.630060288 +0800
@@ -1,4 +1,4 @@
-#!/temp/x32-480-posix-dwarf-r2/mingw32/opt/bin/python2.7.exe
+#!/usr/bin/python
import sys
import os
@@ -31,26 +31,23 @@
for opt in opt_flags:
if opt == '--prefix':
- print sysconfig.PREFIX
+ print '../python'
elif opt == '--exec-prefix':
- print sysconfig.EXEC_PREFIX
+ print '../python'
elif opt in ('--includes', '--cflags'):
- flags = ['-I' + sysconfig.get_python_inc(),
- '-I' + sysconfig.get_python_inc(plat_specific=True)]
+ flags = ['-I' + os.path.split(os.path.realpath(__file__))[0] + '/../include/python2.7']
if opt == '--cflags':
- flags.extend(getvar('CFLAGS').split())
+ flags += ['-fno-strict-aliasing -DMS_WIN32 -DMS_WINDOWS -DHAVE_USABLE_WCHAR_T -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes']
print ' '.join(flags)
elif opt in ('--libs', '--ldflags'):
- libs = getvar('LIBS').split() + getvar('SYSLIBS').split()
- libs.append('-lpython'+pyver)
+ libs = ['-lm -lpython2.7 -Wl,--out-implib=libpython2.7.dll.a']
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
# shared library in prefix/lib/.
if opt == '--ldflags':
if not getvar('Py_ENABLE_SHARED'):
- libs.insert(0, '-L' + getvar('LIBPL'))
- libs.extend(getvar('LINKFORSHARED').split())
+ libs.insert(0, '-L' + os.path.split(os.path.realpath(__file__))[0] + '/../lib/python2.7/config')
print ' '.join(libs)
因為Linux下是無法運行開發包中的python.exe的,所以這個補丁借用了ubuntu的python。裡面的cflags和ldflags都是在Windows底下運行原始python-config獲得的。prefix和exec-prefix設成「../python」,可以在編譯完以後,把python開發包拷貝到gdb安裝目錄裡面的python子目錄,這樣運行GDB的時候就不需要設定PYTHONHOME環境變數了。
最後一個事情,確保你的Linux下有arm交叉編譯器,我的是arm-linux-gnueabihf,是啥target就寫啥。
准備工作做完了,開始配置和編譯:
./configure --with-expat --host=i586-mingw32msvc --target=arm-linux-gnueabihf --with-libexpat-prefix=[expat安裝位置] --with-python=[python開發包安裝位置/bin/python.exe]
make
make DESTDIR=[GDB安裝位置] install
然後把GDB安裝位置下面的所有文件拷貝到Windows下,再把python開發包拷貝到同目錄下的python子目錄,大功告成。
如果提示沒找到libpython2.7.dll,那就把GDB安裝目錄的python/bin下的拷貝到bin下。
如果發現生成的exe文件太大了,那就strip一下。
2015年9月12日追加:
在windows下調試時,一般會提示說載入不了共享庫,讓你用"set sysroot"或"set solib-search-path"之類設定路徑的。這個問題可以通過.gdbinit文件,用上面這兩條命令來設定路徑解決,如果想一勞永逸,可以在編譯的時候加上host_configargs環境變數來解決這個問題:
host_configargs=--with-sysroot=E:\MinGW\opt\sysroot-arm ./configure ...
或者
export host_configargs=--with-sysroot=E:\MinGW\opt\sysroot-arm
./configure ...
後面的路徑是你放在windows下的sysroot的位置。
D. Linux下運行python腳本時報:'import site' failed錯誤,如何修改
你是自己重新安裝的python呢?還是linux系統默認的? 系統和Python 版本分別為多少?
E. 如何使用Python動態控制Linux系統的內存佔用百分比
如何使用Python動態控制Linux系統的內存佔用百分比?
近期有網上朋友尋求幫助:如何通過腳本動態控制Linux系統的內存佔用百分比?經過一番網路+編寫調試,終於初步完成了動態控制Linux系統內存佔用百分比。現寫出來以幫助更多的朋友。
1 前言
根據需求是動態控制Linux系統內存佔用百分比,比如當前內存佔用30%,如果設置內存佔用為70%,則需要申請內存使達到佔用70%;如果再降低到40%,則需要釋放部分申請的內存。其實腳本的本質是內存動態申請與釋放。
注意:因為Python腳本運行之前內存有一定佔用,故設定內存佔用不能低於該百分比。
2 內存動態申請
通過查詢資料,使用Python動態申請內存塊,可以使用ctypes包中的函數,導入包及代碼如下所示:
>>> from ctypes import *
>>> mem=create_string_buffer(1024)
說明:內存申請使用create_string_buffer()函數,上面申請了1024位元組的內存塊。
下面演示申請100MB內存前後變化
申請前如下圖所示:
使用代碼如下:
>>>mem=create_string_buffer(104857600)
申請後如下圖所示:
從上述兩幅圖中可以看出,申請內存前內存佔用295MB,申請後內存佔用397MB,增加了約100MB內存佔用。
3 內存動態釋放
由於Python對內存是有垃圾回收機制的,採用對象引用計數方式。當對象的引用計數為0時,啟動垃圾回收GC。此處內存動態釋放就是使用該原理。
代碼如下:
>>> mem=None
釋放後內存佔用如下圖所示:
內存佔用由397MB降低到297MB,釋放了100MB內存佔用。
說明:將None賦值給對象mem後,mem對象的引用計數即為0,此時垃圾回收啟動,釋放mem對象佔用的內存。
4 系統總內存、佔用內存檢測
由於需要設定內存佔用百分比,故需要獲取系統總物理內存和佔用內存。本文使用的方法是讀取系統文件「/proc/meminfo」,從中解析出總內存大小以及當前內存佔用大小等內存相關的信息。該文件內容格式如下圖所示:
代碼片段如下所示:
f = open("/proc/meminfo")
lines = f.readlines()
f.close()
for line in lines:
if len(line)< 2:continue
name = line.split(':')[0]
var = line.split(':')[1].split()[0]
mem[name]= long(var)* 1024.0
mem['MemUsed']= mem['MemTotal']- mem['MemFree']
說明:按行讀取meminfo文件內容,創建字典對象mem,將meminfo文件第一列設置為mem對象的鍵值,將meminfo文件第二列數字設置為mem對象的值。
5 獲取用戶輸入百分比
通過讀取鍵盤輸入字元串,然後轉換為數字實現接收用戶輸入的百分比,代碼如下所示:
input_str=raw_input("Input UsedMemory`s Rate or q to exit:")
rate=float(input_str)
注意:此處鍵盤輸入的都是字元串,需要進行字元串轉換為數字,使用float()或long()函數進行轉換。
6 動態設置內存佔用百分比測試
測試使用兩個Python腳本文件,分別是test.py和mem_rate.py,其功能分別是查看當前內存佔用和動態設定內存佔用百分比。如下圖所示:
注意:上述兩個文件需要使用「chmod +x *.py」修改為可執行屬性。
6.1 查看當前內存佔用
查看當前內存佔用百分比,使用上述test.py文件,運行命令為「./test.py」,運行結果如下圖所示:
當前使用內存為320MB,佔用百分比為17%。
6.2 動態設置內存佔用百分比
動態設置內存佔用百分比使用上述mem_rate.py腳本,注意該腳本文件第一行代碼為「#!/usr/bin/python2.6」,表示該腳本使用python2.6程序運行。該行需要修改為待運行Linux系統中Python實際的安裝程序路徑。
動態內存百分比設置界面如下圖所示:
處於待輸入狀態。另外顯示了當前內存佔用(321MB),總內存大小(1869MB)以及內存佔用百分比(17%)。
如果此時設置內存佔用百分比為80%,則腳本會每次申請10MB空間,直至內存佔用接近或等於80%為止。如下圖所示:
內存申請過程如下圖所示:
內存申請過程中佔用百分比變化為:35%,45%,56%,70%,…
mem_rate.py運行過程如下圖所示:
內存申請過程中佔用變化為:1461MB,1471MB,1481MB,1491MB。
此時如果內存佔用百分比設置為20%,則需要釋放一部分內存。
test.py腳本運行過程如下圖所示:
由於釋放內存運行較快,抓取到最後結果
內存佔用為20%。
mem_rate.py腳本運行過程如下圖所示:
內存釋放過程中內存佔用為:413MB,403MB,393MB,383MB,最後內存佔用穩定在20%,383MB。
輸入「q」或「Q」退出內存佔用百分比設定過程,如下圖所示:
此時內存佔用如下圖所示:
內存佔用恢復到運行mem_rate.py腳本之前狀態,17%,321MB。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
附:完整Python腳本代碼
test.py
------------------------------------------------------------------------------------------------
#!/usr/bin/python2.6
def memory_stat():
mem = {}
f = open("/proc/meminfo")
lines = f.readlines()
f.close()
for line in lines:
if len(line)< 2:continue
name = line.split(':')[0]
var = line.split(':')[1].split()[0]
mem[name]= long(var)* 1024.0
mem['MemUsed']= mem['MemTotal']- mem['MemFree']
# - mem['Buffers']- mem['Cached']
return mem
mem=memory_stat()
print("Used(MB):%d"%(long(mem['MemUsed'])/1024/1024))
print("Rate:%d%%"%(100*long(mem['MemUsed'])/float(mem['MemTotal'])))
§§§§§§§§§§§§§§§§§§§§§§§§§§
mem_rate.py
---------------------------------------------------
#!/usr/bin/python2.6
from ctypes import *
# Get Memory Info(Total, Used... Byte)
def get_memory_stat():
mem = {}
f = open("/proc/meminfo")
lines = f.readlines()
f.close()
for line in lines:
if len(line)< 2:continue
name = line.split(':')[0]
var = line.split(':')[1].split()[0]
mem[name]= long(var)* 1024.0
mem['MemUsed']= mem['MemTotal']- mem['MemFree']
# Return MemroyInfo Object
return mem
# Get Simple Memory Info
def get_memory_info(mem):
# Byte -> MB
n=1024* 1024
used=float(mem['MemUsed'])/ n
total=float(mem['MemTotal'])/ n
rate=used/total* 100
smp={'used':used,'total':total,'rate':rate}
return smp
# Display Current Memory Info
def print_memory_info(mem):
# Get SimpleMemory Info
smp=get_memory_info(mem)
print("Used(MB):%d\tTotal(MB):%d\tUsedRate:%d%%"%(smp['used'], smp['total'], smp['rate']))
# Get Rate Of Memory Used To Be Setted(Integer Formate)
def input_memory_used_rate(org_rate):
# Byte -> MB
n=1024* 1024
while(True):
mem=get_memory_stat()
print_memory_info(mem)
input_str=raw_input("Input UsedMemory`s Rate or q to exit:")
if(len(input_str)== 0):
continue
if("q"== input_str):
info={'rate':0,'used':mem['MemUsed']/ n}
return info
if("Q"== input_str):
info={'rate':0,'used':mem['MemUsed']/ n}
return info
try:
rate=float(input_str)
if((rate>=org_rate)and (rate<=95)):
info={'rate':rate,'used':mem['MemUsed']/ n}
return info
else:
print("Please inputa valid number(%d%%~95%%)."%(org_rate))
except:
print("Please inputa valid number(%d%%~95%%)."%(org_rate))
# Set Rate Of Memory Used
def set_memory_used_rate(new_rate, total, pre_used,list):
if(new_rate==0):
return None
dest_mem=total* new_rate /100.0
# 10MB
mb10=10485760
n_chg=10
# Free Memory OrAllocate Memory ?
is_new=dest_mem>pre_used
cur_used=pre_used
while(True):
# To Calc FreeMemory Or Allocate Memory ?
need_new=dest_mem-n_chg>=pre_used
need_del=dest_mem+n_chg<=pre_used
# Need To AllocateMemory
if(is_new):
if(need_new):
p=create_string_buffer(mb10)
list.append(p)
dest_mem=dest_mem-n_chg
cur_used=cur_used+n_chg
else:
return"end"
# Need To FreeMemory
else:
idx=len(list)-1
if(need_deland (idx>=0)):
p=list[idx]
del list[idx]
p=None
dest_mem=dest_mem+n_chg
cur_used=cur_used-n_chg
else:
return"end"
print("****** MemoryUsed(MB):%d"%(cur_used))
# Entry Of Program
# List Of Memory Object, 10MB Of One Object
list=[]
# Get Current Memory Info
mem=get_memory_stat()
# Get Simple Memory Info
smp=get_memory_info(mem)
org_rate=smp['rate']
total=smp['total']
while(True):
# Get Rate OfMemory To Be Used
info=input_memory_used_rate(org_rate)
new_rate=float(info['rate'])
pre_used=float(info['used'])
# Set Rate OfMemory To Be Used
rtn=set_memory_used_rate(new_rate, total, pre_used, list)
if(not rtn):
print("bye!")
exit()
F. Python腳本在Linux上怎麼運行
一、首先下載安裝python,建議安裝2.7版本以上,3.0版本以下,由於3.0版本以上不向下兼容,體驗較差。
G. 在windows上的python 連接 linux 並做點操作
訪問SqlServer
復制代碼代碼如下:
>>> import pyodbc
>>>cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=192.168.1.100\\sql;DATABASE=testDB;UID=sa;PWD=myPassword')
>>>cursor = cnxn.cursor()
>>>cursor.execute("select * from Tb")
二、Linux下配置Python訪問SqlServer
環境:CentOS 6.2 + Sqlserver 2008
1、安裝freetds:
復制代碼代碼如下:
yum install freetds*
2、安裝pyodbc:
復制代碼代碼如下:
yum install pyodbc
修改odbc配置:
復制代碼代碼如下:
vi /etc/odbcinst.ini
添加FreeTDS驅動:
復制代碼代碼如下:
[SQL Server]
Description = FreeTDS ODBC driver for MSSQL
Driver = /usr/lib/libtdsodbc.so
Setup = /usr/lib/libtdsS.so
FileUsage = 1
3、測試
復制代碼代碼如下:
#python
>>> import pyodbc
>>>cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=192.168.1.100\\sql;DATABASE=testDB;UID=sa;PWD=myPassword')
>>>cursor = cnxn.cursor()
>>>cursor.execute("select * from Tb")
H. 在windows上開發的python程序能直接在linux上跑嗎
有些東西是平台相關的,比如說你在程序里用余衡了win32com或者winhook,那就註定只能在win上跑…然而只要注意不用睜蔽到這些,或者豎早做代碼里有對平台的判斷,不同平台不同方案的話也可以正常工作。
I. linux上啟動python程序,shell腳本服務怎麼編寫
1.只能夠輸入Python命令。
在Python交互模式下輸入Python代碼,而不要輸入系統的命令。
2.在交互模式下列印語句不是必須的。
在交互模式下不需要輸入完整的列印語句,解釋器自動列印表達式的結果,但是在文件中則需要寫print語句來列印結果。
3.提示符的變換和復合語句。
當在交互模式下輸入兩行或多行的復合語句時,提示符會由>>>變成;如果要結束復合語句的輸入並執行它,那麼必須按下Enter鍵兩次,復合語句才會被執行。
4.交互提示模式一次運行一條語句。
當你想測試某一條命令的時候,交互模式是一個很好的測試方法,輸入然後回車即可猛高大看到執行結果枝豎,非常方便,當然對於復合語句來說,只要最後按兩次Enter鍵即可運行代碼,看到執行結果。
具體如下:
1、簡介
Linux操作系統是基於UNIX操作系統發展而來的一種克隆系統,它誕生於1991年的[Linux桌面]10月5日(這是第一次正式向外公布的時間)。以後藉助於Internet網路,並通過全世界各地計算機愛好者的共同努力,已成為今天世界上使用最多的一種UNIX類操作系統,並且使用人數還在迅猛增長。
2、基本信息
Linux[2]操作系統是UNIX操作系統的一種克隆系統,它誕生linux系統於1991年的10月5日(這是第一次正式向外公布的時間)。以後藉助於Internet網路,並通過全世界各地計算機愛好者的共同努力,已成為今天世界上使用最多的一種UNIX類操作系統,並且使用人數還在迅猛增長。
3、分區規定
設備管理在Linux中,每一個硬體設備都映射到一個系統的文件,對於硬碟、光碟機等,IDE或SCSI設備也不例外。Linux把各種IDE設備分配了一個由hd前綴組成念鋒的文件;而對於各種SCSI設備,則分配了一個由sd前綴組成的文件。
J. Linux 下Python 腳本編寫的&quot;奇技淫巧&quot;
「 生命完美的答案,無非走過沒有遺憾 ---《天藍》」
「如何能夠解析腳本運行命令行選項(位於 sys.argv 中)」
argparse 模塊可被用來解析命令行選項
常用來定義一個腳本的說明文檔,一般我們寫python腳本會通過 if..else 的方式來提供一個腳本說明文檔,python不支持switch。所以很麻煩,其實,我們可以通過 argparse 來編寫說明文檔。
我們來看看怎麼執行一個python腳本
對於熟悉Linux的小夥伴下面的文檔在熟悉不過了,這個一個標准Linxu軟體包的說明文檔,文檔中定義是軟體包的說明
來看看這個腳本是如何編寫的
為了解析命令行選項, 首先要創建一個 ArgumentParser 實例, 使用 add_argument() 方法聲明你想要支持的選項。在每個 add-argument() 調用中:
dest 參數指定解析結果被指派給屬性的名字。 metavar 參數被用來生成幫助信息。
action 參數 指定跟屬性對應的處理邏輯,通常的 值為 store , 被用來存儲 某個值 或將 多個參數值收集到一個列表中 。
nargs 參數收集 所有剩餘的命令行參數到一個列表中。在本例中它被用來構造一個文件名列表
action='store_true' 根據參數是否存在來設置一個位置 Boolean 標志:
action='store' 參數接受一個單獨值並將其存儲為一個字元串
如果一個都沒有,會提示缺少參數 -p/--pat
choices={'slow', 'fast'}, 參數說明接受一個值,但是會將其和可能的選擇值做比較,以檢測其合法性:
一旦參數選項被指定,你就可以執行 parser.parse() 方法了。它會處理 sys.argv 的值並返回一個結果實例。每個參數值會被設置成該實例中 add_argument() 方法的 dest 參數指定的屬性值。
還很多種其他方法解析命令行選項。可以會手動地處理 sys.argv 或者使用 getopt 模塊 。但是,如果你採用本節的方式,將會減少很多冗餘代碼,底層細節 argparse 模塊 已經幫你處理好了。你可能還會碰到使用 optparse 庫解析選項的代碼。盡管 optparse 和 argparse 很像 ,但是後者更先進,因此在新的程序中你應該使用它。
「你寫了個腳本,運行時需要一個密碼。此腳本是互動式的,因此不能將密碼在腳本中硬編碼,而是需要彈出一個密碼輸入提示,讓用戶自己輸入。」
Python 的 getpass 模塊 正是你所需要的。你可以讓你很輕松地彈出密碼輸入提示,並且不會在用戶終端顯示密碼。
代碼中 getpass.getuser() 不會彈出用戶名的輸入提示。它會根據該 用戶的 shell 環境 或者會依據 本地系統的密碼庫 (支持 pwd 模塊的平台)來使用 當前用戶的登錄名
在bash中編寫pytohn腳本接收外部數據的方式,一般情況下,對於一般變數,我們用命令行變數的方式比較多(手動的處理 sys.argv ),對於 文件內容或者bash命令輸出 直接通過腳本內部獲取需要的數據。
其實python 腳本也可以用其他方式來接收 傳遞給他的 文件數據或者bash命令輸出 ,包括將 命令行的輸出 通過 管道傳遞 給該腳本、 重定向文件到該腳本 ,或在 命令行中傳遞一個文件名 或 文件名列表 給該腳本。
這里通過 Python 內置的 fileinput 模塊 ,可以實現重 定向,管道,以文佳輸出 的方式傳遞數據到腳本內部
使用 fileinput.input() 方法可以獲取當前輸入腳本的數據,腳本裡面用一個 FileInput 迭代器接收
文件直接接收
重定向接收
管道方式接收
fileinput.input() 創建並返回一個 FileInput 類的實例,該實例可以被當做一個 上下文管理器 使用。因此,整合起來,如果我們要寫一個列印多個文件輸出的腳本,那麼我們需要在輸出中包含文件名和行號
「你想執行一個外部命令並以 Python 字元串的形式獲取執行結果。」
使用 subprocess.check_output() 函數。
執行下試試
如果被執行的命令以非零碼返回,就會拋出異常。下面的例子捕獲到錯誤並獲取返回碼:
默認情況下, check_output() 僅僅返回輸入到標准輸出的值。如果你需要 同時收集標准輸出和錯誤輸出 ,使用 stderr 參數:
如果你需要用一個超時機制來執行命令,使用 timeout 參數:
通常來講,命令的執行 不需要 使用到 底層 shell 環境(比如 sh、bash) 。一個字元串列表會被傳遞給一個 低級系統命令 ,比如 os.execve() 。
如果你想讓 命令被一個shell 執行 ,傳遞一個字元串參數,並設置參數 shell=True . 有時候你想要 Python 去執行一個復雜的 shell 命令 的時候這個就很有用了,比如管道流、I/O 重定向和其他特性。例如:
是在 shell 中執行命令會存在一定的安全風險,特別是當參數來自於用戶輸入時。這時候可以使用 shlex.quote() 函數 來將參數正確的用雙引用引起來。
使用 check_output() 函數 是執行 外部命令 並獲取其 返回值 的最簡單方式。但是,如果你需要對 子進程做更復雜的交互 ,比如給它發送輸入,你得採用另外一種方法。這時候可直接使用 subprocess.Popen 類。
關於子進程,簡單來看下
也可以進程列表同協程結合的方式。你既可以在子shell中 進行繁重的處理工作,同時也不會讓子shell的I/O受制於終端。
如果直接丟到後台會自動在終端輸出IO
subprocess 模塊對於依賴 TTY 的外部命令不合適用 。例如,你不能使用它來自動化一個用戶輸入密碼的任務(比如一個 ssh 會話)。這時候,你需要使用到第三方模塊了,比如基於著名的 expect 家族的工具(pexpect 或類似的)(pexpect可以理解為Linux下的expect的Python封裝、通過pexpect可以實現對ssh、ftp、passwd、telnet等命令行進行自動交互,而無需人工干涉來達到自動化的目的。比如我們可以模擬一個FTP登錄時所有交互,包括輸入主機地址、用戶名、密碼、上傳文件等,待出現異常還可以進行嘗試自動處理。)
「你想向標准錯誤列印一條消息並返回某個非零狀態碼來終止程序運行」
通過 python 的 raise SystemExit(3) 命令可以主動拋出一個錯誤,通過 sys.stderr.write 將命令寫到標準的輸出端
直接將消息作為參數傳給 SystemExit() ,那麼你可以省略其他步驟
拋出一個 SystemExit 異常,使用錯誤消息作為參數,它會將消息在 sys.stderr 中列印,然後程序以狀態碼 1 退出
「你需要知道當前終端的大小以便正確的格式化輸出。」
使用 os.get terminal size() 函數 來做到這一點。
「復制或移動文件和目錄,但是又不想調用 shell 命令。」
shutil 模塊 有很多便捷的函數可以復制文件和目錄。使用起來非常簡單
這里不多講,熟悉Linux的小夥伴應該不陌生。
默認情況下,對於 符號鏈接 這些命令處理的是它指向的東西文件。例如,如果 源文件 是一個 符號鏈接 ,那麼目標文件將會是 符號鏈接 指向的文件。如果你只想 復制符號鏈接本身 ,那麼需要指定 關鍵字 參數 follow_symlinks
tree() 可以讓你在復制過程中選擇性的忽略某些文件或目錄。你可以提供一個忽略函數,接受一個目錄名和文件名列表作為輸入,返回一個忽略的名稱列表。例如:
對於文件元數據信息, 2() 這樣的函數只能盡自己最大能力來保留它。 訪問時間、創建時間和許可權 這些基本信息會被保留,但是 對於所有者、ACLs、資源 fork 和其他更深層次的文件元信息就說不準了
通常不會去使用 shutil.tree() 函數 來執行 系統備份 。當處理文件名的時候,最好使用 os.path 中的函數來確保最大的可移植性
使用 tree() 復制文件夾的一個棘手的問題是對於錯誤的處理,可以使用異常塊處理,或者通過 參數 ignore dangling symlinks=True 忽略掉無效符號鏈接。
「創建或解壓常見格式的歸檔文件(比如.tar, .tgz 或.zip)」
shutil 模塊擁有兩個函數—— make archive() 和 unpack archive() 可派上用場,
make archive() 的第二個參數是期望的輸出格式。可以使用 get archive formats() 獲取所有支持的歸檔格式列表。
「你需要寫一個涉及到文件查找操作的腳本,比如對日誌歸檔文件的重命名工具,你不想在 Python 腳本中調用 shell,或者你要實現一些 shell 不能做的功能。」
查找文件,可使用 os.walk() 函數 ,傳一個頂級目錄名給它
os.walk() 方法 為我們 遍歷目錄樹 ,每次進入一個目錄,它會返回一個 三元組 ,包含 相對於查找目錄的相對路徑,一個該目錄下的目錄名列表,以及那個目錄下面的文件名列表。
對於每個元組,只需檢測一下目標文件名是否在文件列表中。如果是就使用 os.path.join() 合並路徑。為了避免奇怪的路徑名比如 ././foo//bar ,使用了另外兩個函數來修正結果
os.walk(start) 還有跨平台的優勢。並且,還能很輕松的加入其他的功能。我們再演示一個例子,下面的函數列印所有最近被修改過的文件:
列印10分鍾之前被修改的數據
「怎樣讀取普通.ini 格式的配置文件?」
configparser 模塊 能被用來讀取配置文件
編寫配置文件
如果有需要,你還能修改配置並使用 cfg.write() 方法將其寫回到文件中
「你希望在腳本和程序中將診斷信息寫入日誌文件。」
python 腳本列印日誌最簡單方式是使用 logging 模塊
五個日誌調用( critical(), error(), warning(), info(), debug() )以降序方式表示不同的嚴重級別。 basicConfig() 的 level 參數是一個 過濾器 。所有級別低於此級別的日誌消息都會被忽略掉。每個 logging 操作的參數是一個消息字元串,後面再跟一個或多個參數。構造最終的日誌消息的時候我們使用了 % 操作符來格式化消息字元串。
如果你想使用配置文件,可以像下面這樣修改 basicConfig() 調用:
logconfig.ini
在調用日誌操作前先執行下 basicConfig() 函數方法 ,可以找標准輸出或者文件中輸出
basicConfig() 在程序中只能被執行一次。如果你稍後想改變日誌配置,就需要先獲取 root logger ,然後直接修改它。
更多見日誌模塊文檔https://docs.python.org/3/howto/logging-cookbook.html
「你想給某個函數庫增加日誌功能,但是又不能影響到那些不使用日誌功能的程序。」
對於想要執行日誌操作的函數庫,你應該創建一個專屬的 logger 對象,並且像下面這樣初始化配置:
使用這個配置,默認情況下不會列印日誌,只有配置過日誌系統,那麼日誌消息列印就開始生效
通常來講,不應該在函數庫代碼中 自己配置日誌系統 ,或者是已經有個已經存在的日誌配置了。調用 getLogger( name ) 創建一個和調用模塊同名的 logger 模塊 。由於 模塊 都是唯一的,因此創建的 logger 也將是唯一 的。所以當前進程中只有一個logging會生效。
log.addHandler(logging.NullHandler()) 操作將一個 空處理器 綁定到剛剛已經創建好的 logger 對象 上。一個空處理器默認會忽略調用所有的日誌消息。因此,如果使用該函數庫的時候還沒有配置日誌,那麼將不會有消息或警告出現。
在這里,根日誌被配置成僅僅 輸出 ERROR 或更高級別的消息 。不過, somelib 的日誌級別被單獨配置成可以輸出 debug 級別的消息, 它的優先順序比全局配置高。像這樣更改單獨模塊的日誌配置對於調試來講是很方便的,因為你無需去更改任何的全局日誌配置——只需要修改你想要更多輸出的模塊的日誌等級。(這個還有待研究)
「你想記錄程序執行多個任務所花費的時間」
time 模塊 包含很多函數來執行跟時間有關的函數。盡管如此,通常我們會在此基礎之上構造一個更高級的介面來模擬一個計時器。
這個類定義了一個可以被用戶根據需要啟動、停止和重置的計時器。它會在elapsed 屬性中記錄整個消耗時間。下面是一個例子來演示怎樣使用它:
這里通過 __enter__,__exit__ ,使用 with 語句 以及上下文管理器協議可以省略計時器打開和關閉操作。(關於上下文管理協議,即with語句,為了讓一個對象兼容with語句,必須在這個對象的類中聲明 __enter__和__exit__方法, , __enter__ 在出現with語句被調用, __exit__ 在代碼執行完畢被調用,可以參考open()方法)
在計時中要考慮一個 底層的時間函數問題 。 一般來說, 使用 time.time() 或 time.clock() 計算的時間精度因操作系統的不同會有所不同。而使用 time.perf_counter() 函數可以確保使用系統上面 最精確的計時器 。
「你想對在 Unix 系統上面運行的程序設置內存或 CPU 的使用限制。」
resource 模塊 能同時執行這兩個任務。例如,要限制 CPU 時間,下面的代碼在windows平台執行不了,但是Linux是可以的。
程序運行時, SIGXCPU 信號 在時間過期時被生成,然後執行清理並退出。
這暫時沒有好的Demo...
程序運行到沒有多餘內存時會拋出 MemoryError 異常。
setrlimit() 函數 被用來設置特定資源上面的 軟限制和硬限制 。
setrlimit() 函數 還能被用來設置 子進程數量、打開文件數以及類似系統資源的限制(cgroup) 。
「通過腳本啟動瀏覽器並打開指定的 URL 網頁」
webbrowser 模塊 能被用來啟動一個瀏覽器,並且與平台無關
新窗口打卡網站
當前窗口打開一個tab頁
指定瀏覽器類型,可以使用 webbrowser.get() 函數