[Ubuntu][Python][原創]make_sd_card.py制卡腳本Python文件解讀注釋
剛看時這個腳本代碼太多,是不是看不懂或者難看?其實告訴你寫了這么多代碼就一句有用,其他都是在搞亂七八糟的校驗,防止出錯。關鍵代碼在202行,就這一句有用,其實完全就用202一行代碼搞定了。很多注釋在下面我做了,一看就懂。廢話不多上代碼+注釋。下次放出制卡的sh腳本注釋。

#
#???=======================================================================
#
#?Copyright?(C)?2018,?Hisilicon?Technologies?Co.,?Ltd.?All?Rights?Reserved.
#
#?Redistribution?and?use?in?source?and?binary?forms,?with?or?without
#?modification,?are?permitted?provided?that?the?following?conditions?are?met:
#
#???1?Redistributions?of?source?code?must?retain?the?above?copyright?notice,
#?????this?list?of?conditions?and?the?following?disclaimer.
#
#???2?Redistributions?in?binary?form?must?reproduce?the?above?copyright?notice,
#?????this?list?of?conditions?and?the?following?disclaimer?in?the?documentation
#?????and/or?other?materials?provided?with?the?distribution.
#
#???3?Neither?the?names?of?the?copyright?holders?nor?the?names?of?the
#???contributors?may?be?used?to?endorse?or?promote?products?derived?from?this
#???software?without?specific?prior?written?permission.
#
#?THIS?SOFTWARE?IS?PROVIDED?BY?THE?COPYRIGHT?HOLDERS?AND?CONTRIBUTORS?"AS?IS"
#?AND?ANY?EXPRESS?OR?IMPLIED?WARRANTIES,?INCLUDING,?BUT?NOT?LIMITED?TO,?THE
#?IMPLIED?WARRANTIES?OF?MERCHANTABILITY?AND?FITNESS?FOR?A?PARTICULAR?PURPOSE
#?ARE?DISCLAIMED.?IN?NO?EVENT?SHALL?THE?COPYRIGHT?HOLDER?OR?CONTRIBUTORS?BE
#?LIABLE?FOR?ANY?DIRECT,?INDIRECT,?INCIDENTAL,?SPECIAL,?EXEMPLARY,?OR
#?CONSEQUENTIAL?DAMAGES?(INCLUDING,?BUT?NOT?LIMITED?TO,?PROCUREMENT?OF
#?SUBSTITUTE?GOODS?OR?SERVICES;?LOSS?OF?USE,?DATA,?OR?PROFITS;?OR?BUSINESS
#?INTERRUPTION)?HOWEVER?CAUSED?AND?ON?ANY?THEORY?OF?LIABILITY,?WHETHER?IN
#?CONTRACT,?STRICT?LIABILITY,?OR?TORT?(INCLUDING?NEGLIGENCE?OR?OTHERWISE)
#?ARISING?IN?ANY?WAY?OUT?OF?THE?USE?OF?THIS?SOFTWARE,?EVEN?IF?ADVISED?OF?THE
#?POSSIBILITY?OF?SUCH?DAMAGE.
#???=======================================================================
#
'''common?installation'''
import?os
import?platform
import?signal
import?subprocess
import?time
import?yaml
import?sys
NETWORK_CARD_DEFAULT_IP="192.168.0.2"?#?網卡默認的IP地址
USB_CARD_DEFAULT_IP="192.168.1.2"?#?開發板USB登錄默認IP
VERSION_INFO_URL?=?"https://raw.githubusercontent.com/Ascend/tools/master/versioninfo.yaml"
CURRENT_PATH?=?os.path.dirname(
os.path.realpath(__file__))
SD_CARD_MAKING_PATH?=?os.path.join(CURRENT_PATH,?"sd_card_making")
MIN_DISK_SIZE?=?7?*?1024?*?1024?*?1024?#最小容量限制
#?這個腳本寫了一大堆代碼其實就是為這個命令服務
MAKING_SD_CARD_COMMAND?=?"bash?{path}/make_ubuntu_sd.sh?"?+?"?{dev_name}"?+?\
"?{pkg_path}?{ubuntu_file_name}?{ascend_developerkit_file_name}"?+?\
"?"?+?NETWORK_CARD_DEFAULT_IP?+?"?"?+?USB_CARD_DEFAULT_IP?+?\
"?>?{log_path}/make_ubuntu_sd.log?"
#?在終端執行命令,python調用,這個和windows一樣,其他編程調用終端的程序去運行腳本
def?execute(cmd,?timeout=3600,?cwd=None):
'''execute?os?command'''
#?print(cmd)
is_linux?=?platform.system()?==?'Linux'
if?not?cwd:
cwd?=?os.getcwd()
process?=?subprocess.Popen(cmd,?cwd=cwd,?bufsize=32768,?stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,?shell=True,
preexec_fn=os.setsid?if?is_linux?else?None)
t_beginning?=?time.time()
#?cycle?times
time_gap?=?0.01
str_std_output?=?""
while?True:
str_out?=?str(process.stdout.read().decode())
str_std_output?=?str_std_output?+?str_out
if?process.poll()?is?not?None:
break
seconds_passed?=?time.time()?-?t_beginning
if?timeout?and?seconds_passed?>?timeout:
if?is_linux:
os.kill(process.pid,?signal.SIGTERM)
else:
process.terminate()
return?False,?process.stdout.readlines()
time.sleep(time_gap)
str_std_output?=?str_std_output.strip()
#?print(str_std_output)
std_output_lines_last?=?[]
std_output_lines?=?str_std_output.split("\n")
for?i?in?std_output_lines:
std_output_lines_last.append(i)
if?process.returncode?!=?0?or?"Traceback"?in?str_std_output:
return?False,?std_output_lines_last
return?True,?std_output_lines_last
def?print_process(string,?is_finished=False):
if?string?==?""?or?string?is?None?or?is_finished:
print("..........?..........?..........?..........?100%",?end='\r')
print("")
else:
string?=?string.split("..........?",?1)[1]
string?=?string.split("%")[0]?+?"%"
print(string,?end='\r')
def?execute_wget(cmd,?timeout=86400,?cwd=None):
'''execute?os?command'''
#?print(cmd)
is_linux?=?platform.system()?==?'Linux'
if?not?cwd:
cwd?=?os.getcwd()
process?=?subprocess.Popen(cmd,?cwd=cwd,?bufsize=1,?stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,?shell=True,
preexec_fn=os.setsid?if?is_linux?else?None)
t_beginning?=?time.time()
#?cycle?times
time_gap?=?0.01
str_std_output?=?""
process_str?=?""
while?True:
str_out?=?str(process.stdout.readline())
if?"......"?in?str_out:
process_str?=?str_out
print_process(process_str)
str_std_output?=?str_std_output?+?str_out
if?process.poll()?is?not?None:
break
seconds_passed?=?time.time()?-?t_beginning
if?timeout?and?seconds_passed?>?timeout:
if?is_linux:
os.kill(process.pid,?signal.SIGTERM)
else:
process.terminate()
print("")
return?False
time.sleep(time_gap)
if?process.returncode?!=?0?or?"Traceback"?in?str_std_output:
print("")
return?False
print_process(process_str,?True)
return?True
def?check_sd(dev_name):
#?執行shell命令?fdisk?-l?2>/dev/null?|?grep?"Disk?你的USB名稱:"
ret,?disk?=?execute(
"fdisk?-l?2>/dev/null?|?grep?\"Disk?{dev_name}:\"".format(dev_name=dev_name))
if?not?ret?or?len(disk)?>?1:
#?如果提示這個錯誤說明調用上面的shell命令,沒有找到disk,此時你可以手動在終端執行看看什么原因
print(
"[ERROR]?Can?not?get?disk,?please?use?fdisk?-l?to?check?available?disk?name!")
return?False
#?查詢掛載的磁盤到list
ret,?mounted_list?=?execute("df?-h")
#?返回None表示沒有查詢到,如果出現這個錯誤提示,請自己在終端執行df-h看看什么情況
if?not?ret:
print("[ERROR]?Can?not?get?mounted?disk?list!")
return?False
#?df?-h執行的結果,我電腦插的有SD卡
#?Filesystem??????Size??Used?Avail?Use%?Mounted?on
#?udev????????????3.6G?????0??3.6G???0%?/dev
#?tmpfs???????????742M??9.6M??732M???2%?/run
#?/dev/sda1???????289G???21G??256G???8%?/
#?tmpfs???????????3.7G???22M??3.6G???1%?/dev/shm
#?tmpfs???????????5.0M??4.0K??5.0M???1%?/run/lock
#?tmpfs???????????3.7G?????0??3.7G???0%?/sys/fs/cgroup
#?tmpfs???????????742M???60K??742M???1%?/run/user/1002
#?vmhgfs-fuse?????376G??203G??174G??54%?/mnt/hgfs
#?tmpfs???????????742M???64K??742M???1%?/run/user/1003
#?/dev/sdb3????????24G??179M???22G???1%?/media/lwl/ubuntu_fs1
#?/dev/sdb2???????976M??1.3M??924M???1%?/media/lwl/ubuntu_fs
#?/dev/sdb1???????4.8G??621M??4.0G??14%?/media/lwl/ubuntu_fs2
#?查詢系統盤,并送入unchanged_disk_list
unchanged_disk_list?=?[]
for?each_mounted_disk?in?mounted_list:
disk_name?=?each_mounted_disk.split()[0]
disk_type?=?each_mounted_disk.split()[5]
if?disk_type?==?"/boot"?or?disk_type?==?"/":
unchanged_disk_list.append(disk_name)
unchanged_disk?=?"?".join(unchanged_disk_list)
#?從USB信息中分割出實際的磁盤容量
disk_size_str?=?disk[0].split(",")[1]
disk_size_str?=?disk_size_str.split()[0]
disk_size?=?int(disk_size_str)
if?dev_name?not?in?unchanged_disk?and?disk_size?>=?MIN_DISK_SIZE:
return?True
#?經過大量的用戶反饋,這個錯誤經常出現,原因是disk_size?>=?MIN_DISK_SIZE不成立
#?因為202-204代碼把磁盤容量有時候會分割錯,因為有的系統顯示是28.7G,有的卻顯示28,7G結果割出來7
#?出現這個問題,在確保SD卡足夠情況下,202代碼改成
#?disk_size_str?=?disk[0].split(",?")[1]?就是,后面加個空格
print("[ERROR]?Invalid?SD?card?or?size?is?less?then?8G,?please?check?SD?Card.")
return?False
def?parse_download_info(ascend_version):
version_info_file_name?=?os.path.basename(VERSION_INFO_URL)
version_info_path?=?os.path.join(
CURRENT_PATH,?version_info_file_name)
ret?=?execute_wget("wget?-O?{name}?{url}?--no-check-certificate".format(
name=version_info_path,?url=VERSION_INFO_URL))
if?not?ret?or?not?os.path.exists(version_info_path):
print(
"[ERROR]?Can?not?download?versioninfo.yaml,?please?check?your?network?connection.")
execute("rm?-rf?{path}".format(path=version_info_path))
return?False,?"",?"",?""
version_info_file?=?open(
version_info_path,?'r',?encoding='utf-8')
version_info_dict?=?yaml.load(
version_info_file)
ascend_version_dict?=?version_info_dict.get("mini_developerkit")
if?ascend_version?==?""?or?ascend_version?==?ascend_version_dict.get("latest_version"):
ascend_developerkit_url?=?ascend_version_dict.get("url")
ascend_sd_making_url?=?ascend_version_dict.get("sd_making_url")
ubuntu_version?=?ascend_version_dict.get(
"compatibility").get("ubuntu")[0]
else:
version_list?=?ascend_version_dict.get("archived_versions")
for?each_version?in?version_list:
if?ascend_version?==?each_version.get("version"):
ascend_developerkit_url?=?each_version.get("url")
ascend_sd_making_url?=?each_version.get("sd_making_url")
ubuntu_version?=?each_version.get(
"compatibility").get("ubuntu")[0]
break
ubuntu_version_dict?=?version_info_dict.get("ubuntu")
for?each_version?in?ubuntu_version_dict:
if?ubuntu_version?==?each_version.get("version"):
ubuntu_url?=?each_version.get("url")
break
version_info_file.close()
if?ascend_developerkit_url?==?""?or?ascend_sd_making_url?==?""?or?ubuntu_url?==?"":
return?False,?"",?"",?""
return?True,?ascend_developerkit_url,?ascend_sd_making_url,?ubuntu_url
def?process_local_installation(dev_name):
confirm_tips?=?"Please?make?sure?you?have?installed?dependency?packages:"?+?\
"\n\t?apt-get?install?-y?qemu-user-static?binfmt-support?gcc-aarch64-linux-gnu?g++-aarch64-linux-gnu\n"?+?\
"Please?input?Y:?continue,?other?to?install?them:"
confirm?=?input(confirm_tips)?#手動提示輸入
confirm?=?confirm.strip()?#?刪首尾空
if?confirm?!=?"Y"?and?confirm?!=?"y":
return?False
#?刪除日志目錄
execute("rm?-rf?{path}_log/*".format(path=SD_CARD_MAKING_PATH))
#?重新創建日志目錄
execute("mkdir?-p?{path}_log".format(path=SD_CARD_MAKING_PATH))
log_path?=?"{path}_log".format(path=SD_CARD_MAKING_PATH)
#?在當前路徑找有沒有mini_developerkit包
ret,?paths?=?execute(
"find?{path}?-name?\"mini_developerkit*.rar\"".format(path=CURRENT_PATH))
if?not?ret:
print("[ERROR]?Can?not?fine?mini?eveloperkit?package?in?current?path")
return?False
#?只允許有一個mini_developerkit包
if?len(paths)?>?1:
print(
"[ERROR]?Too?many?mini?developerkit?packages,?please?delete?redundant?packages.")
return?False
ascend_developerkit_path?=?paths[0]
ascend_developerkit_file_name?=?os.path.basename(ascend_developerkit_path)
#?看看腳本下面有沒有make-ubuntu-sd.sh
ret,?paths?=?execute(
"find?{path}?-name?\"make-ubuntu-sd.sh\"".format(path=CURRENT_PATH))
if?not?ret:
print("[ERROR]?Can?not?fine?make_ubuntu_sd.sh?in?current?path")
return?False
#?看看腳本下面有沒有ubuntu鏡像,注意下載的鏡像不能亂改名字,如果有錯誤提示
#?要么你沒有下載鏡像,要么你把下載鏡像名字給亂改了
ret,?paths?=?execute(
"find?{path}?-name?\"ubuntu*server*arm*.iso\"".format(path=CURRENT_PATH))
if?not?ret:
print("[ERROR]?Can?not?fine?ubuntu\?package?in?current?path")
return?False
if?len(paths)?>?1:
print("[ERROR]?Too?many?ubuntu?packages,?please?delete?redundant?packages.")
return?False
ubuntu_path?=?paths[0]
ubuntu_file_name?=?os.path.basename(ubuntu_path)
#?這個python腳本就這一句有用,其他都是輔助,或者說整個腳本就這一句起了實際制卡作用
print("Step:?Start?to?make?SD?Card.?It?need?some?time,?please?wait...")
execute(MAKING_SD_CARD_COMMAND.format(path=CURRENT_PATH,?dev_name=dev_name,?pkg_path=CURRENT_PATH,
ubuntu_file_name=ubuntu_file_name,
ascend_developerkit_file_name=ascend_developerkit_file_name,?log_path=log_path))
#?make_ubuntu_sd.result會存儲制卡的結果,如果不是Success就表示出了問題
ret?=?execute("grep?Success?{log_path}/make_ubuntu_sd.result".format(log_path=log_path))
if?not?ret[0]:
#?很多用戶反饋這個錯誤提示后查看日志沒有什么有用信息,我們只能看終端打印的信息排查問題
print("[ERROR]?Making?SD?Card?failed,?please?check?%s/make_ubuntu_sd.log?for?details!"?%?log_path)
return?False
return?True
#?通過網絡方式連接方式安裝,由于安裝包很大,網絡速度等問題,不推薦這種方式
def?process_internet_installation(dev_name,?ascend_version):
print("Step:?Downloading?version?information...")
ret?=?parse_download_info(ascend_version)?#?校驗版本號
#?版本不對就提示一下
if?not?ret[0]:
print("Can?not?find?valid?versions,?please?try?to?get?valid?version:?python3?sd_card_making.py?list")
return?False
ascend_developerkit_url?=?ret[1]
ascend_sd_making_url?=?ret[2]
ubuntu_url?=?ret[3]
execute("rm?-rf?{path}_log/*".format(path=SD_CARD_MAKING_PATH))
execute("mkdir?-p?{path}_log".format(path=SD_CARD_MAKING_PATH))
log_path?=?"{path}_log".format(path=SD_CARD_MAKING_PATH)
#?下載developerkit包,這樣免除了離線的校驗
print("Step:?Downloading?developerkit?package...")
ascend_developerkit_file_name?=?os.path.basename(ascend_developerkit_url)
ascend_developerkit_path?=?os.path.join(
CURRENT_PATH,?ascend_developerkit_file_name)
if?os.path.exists(ascend_developerkit_path):
print("%s?is?already?downloaded,?skip?to?download?it."?%
ascend_developerkit_path)
else:
ret?=?execute_wget("wget?-O?{name}?{url}?--no-check-certificate".format(
name=ascend_developerkit_path,?url=ascend_developerkit_url))
if?not?ret?or?not?os.path.exists(ascend_developerkit_path):
print("[ERROR]?Download?develperkit?package?failed,?Please?check?%s?connection."?%
ascend_developerkit_url)
execute("rm?-rf?{path}".format(path=ascend_developerkit_path))
return?False
#?下載制卡腳本
print("Step:?Downloading?SD?Card?making?scripts...")
ascend_sd_making_file_name?=?os.path.basename(ascend_sd_making_url)
ascend_sd_making_path?=?os.path.join(
CURRENT_PATH,?ascend_sd_making_file_name)
ret?=?execute_wget("wget?-O?{name}?{url}?--no-check-certificate".format(
name=ascend_sd_making_path,?url=ascend_sd_making_url))
if?not?ret?or?not?os.path.exists(ascend_developerkit_path):
print("[ERROR]?Download?SD?Card?making?scripts?failed,?Please?check?%s?connection."?%
ascend_sd_making_url)
execute("rm?-rf?{path}".format(path=ascend_sd_making_path))
return?False
#?下載Ubuntu鏡像
print("Step:?Downloading?Ubuntu?iso...")
ubuntu_file_name?=?os.path.basename(ubuntu_url)
ubuntu_path?=?os.path.join(CURRENT_PATH,?ubuntu_file_name)
if?os.path.exists(ubuntu_path):
print("%s?is?already?downloaded,?skip?to?download?it."?%?ubuntu_path)
else:
ret?=?execute_wget(
"wget?-O?{name}?{url}?--no-check-certificate".format(name=ubuntu_path,?url=ubuntu_url))
if?not?ret?or?not?os.path.exists(ascend_developerkit_path):
print(
"[ERROR]?Download?Ubuntu?iso?failed,?Please?check?%s?connection."?%?ubuntu_url)
execute("rm?-rf?{path}".format(path=ubuntu_path))
return?False
#?安裝一些依賴
print("Step:?Installing?system?dependency...")
ret?=?execute(
"apt-get?install?-y?qemu-user-static?binfmt-support?gcc-aarch64-linux-gnu?g++-aarch64-linux-gnu")
if?not?ret[0]:
print("[ERROR]?Install?system?dependency?failed,?please?check:"?+
"\n\tapt-get?install?-y?qemu-user-static?binfmt-support?gcc-aarch64-linux-gnu?g++-aarch64-linux-gnu\n\tapt-get?install?-y?qemu-user-static?binfmt-support?gcc-aarch64-linux-gnu?g++-aarch64-linux-gnu")
#?執行制卡腳本
print("Step:?Start?to?make?SD?Card.?It?need?some?time,?please?wait...")
execute(MAKING_SD_CARD_COMMAND.format(path=CURRENT_PATH,?dev_name=dev_name,
pkg_path=CURRENT_PATH,?ubuntu_file_name=ubuntu_file_name,
ascend_developerkit_file_name=ascend_developerkit_file_name,
log_path=log_path))
ret?=?execute("grep?Success?{log_path}/make_ubuntu_sd.result".format(log_path=log_path))
if?not?ret[0]:
print("[ERROR]?Making?SD?Card?failed,?please?check?%s/make_ubuntu_sd.log?for?details!"?%?log_path)
return?False
return?True
#?打印一些提示信息
def?print_usage():
print("Usage:?")
print("\t[internet]:?python3?make_sd_card.py?internet?[SD?Name]")
print("\t?????????????????Use?latest?version?to?make?SD?card.")
print("\t[internet]:?python3?make_sd_card.py?internet?[SD?Name]?[Version]")
print("\t?????????????????Use?given?version?to?make?SD?card.")
print("\t[local???]:?python3?make_sd_card.py?local?[SD?Name]")
print("\t?????????????????Use?local?given?packages?to?make?SD?card.")
def?main():
'''sd?card?making'''
command?=?""
dev_name?=?""
version?=?""
#?參數超過3個的,取出執行命令(網絡還是離線)和USB名稱
if?(len(sys.argv)?>=?3):
command?=?sys.argv[1]
dev_name?=?sys.argv[2]
#?參數超過4個的,第4個參數是版本號
if?(len(sys.argv)?>=?4):
version?=?sys.argv[3]
#?參數必須為3個及其以上,否則不會制卡
if?command?==?"internet"?and?(len(sys.argv)?==?3?or?len(sys.argv)?==?4):
print("Begin?to?make?SD?Card...")
elif?command?==?"local"?and?len(sys.argv)?==?3:
print("Begin?to?make?SD?Card...")
else:
print("Invalid?Command!")
print_usage()
exit(-1)
#?檢查U盤名稱是否合法,如果不合法不會制卡
ret?=?check_sd(dev_name)
if?not?ret:
exit(-1)#退出程序
if?command?==?"internet":#?執行在線安裝函數
result?=?process_internet_installation(dev_name,?version)
else:
result?=?process_local_installation(dev_name)#?執行離線安裝函數
#?執行上面的結果為True就是制卡成功,否則就是失敗
if?result:
print("Make?SD?Card?successfully!")
exit(0)
else:
exit(-1)
if?__name__?==?'__main__':
main()?#?程序主函數的入口調用,打開此文件從此函數開始執行
python
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。