1 前言
1.1 項(xiàng)目背景
這段時(shí)間博主在寫一些編譯構(gòu)建的腳本,考慮到知識(shí)的儲(chǔ)備性,之前對bash shell解除最多,而且我們的編譯環(huán)境是在Linux下進(jìn)行,所以我優(yōu)選了bash shell腳本。
1.2 功能描述
期間我寫了一個(gè)腳本,大致的功能就是獲取當(dāng)前操作系統(tǒng)是MacOS還是Linux,如果是Linux的話,還需要知道是Linux32還是Linux64。
2 場景分析
2.1 腳本實(shí)現(xiàn)
我們都知道Linux系統(tǒng)下有個(gè)uname
命令可以輸出當(dāng)前系統(tǒng)的詳細(xì)信息,而MacOS上由于它是Unix系統(tǒng)演變來的,所以它也是支持這個(gè)命令的。 經(jīng)過一番研究,我就決定使用uname-a
來獲取輸出信息,然后從輸出信息里面檢索關(guān)鍵字,進(jìn)而判斷是什么系統(tǒng)。 腳本實(shí)現(xiàn)代碼如下:
-
#! /bin/bash -e
-
function get_os()
-
{
-
echo "begin to get OS ..."
-
os=`uname -a | grep Darwin`
-
if [ "$os" != "" ]; then
-
host_os_name=OSX
-
else
-
os=`uname -a | grep x86_64`
-
if [ "$os" != "" ]; then
-
host_os_name=Linux64
-
else
-
host_os_name=Linux32
-
fi
-
fi
-
echo "get OS name: $host_os_name"
-
}
-
function do_other_things()
-
{
-
echo "do other things ..."
-
}
-
get_os
-
do_other_things
-
exit 0
2.2 問題復(fù)現(xiàn)
從功能邏輯上分析,沒有任何問題,結(jié)果我在Linux-x64上面一跑,出乎意料了:
-
bash_shell_e$ ./test_shell_e.sh
-
begin to get OS ...
感覺腳本壓根就沒跑完啊?怎么回事?
2.3 問題分析
調(diào)試代碼,先從邏輯上分析沒有問題,再使用萬能的print大法
,不過再bash shell里面就要用echo
了。 通過一行行echo添加log,最終定位到是:
-
os=`uname -a | grep Darwin`
執(zhí)行完這句之后,后面的if
語句就沒跑進(jìn)去! 但是uname-a|grepDarwin
在我的機(jī)器上是可以執(zhí)行的,并不會(huì)報(bào)錯(cuò):
-
bash_shell_e$ uname -a | grep Darwin
-
bash_shell_e$
雖然是啥也沒輸出。 我們都知道在bash shell里面是通過echo $?
來判斷上一條命令執(zhí)行是否成功的:
-
bash_shell_e$ echo $?
-
1
-
bash_shell_e$
-
bash_shell_e$ ls
-
test_shell_e.sh
-
bash_shell_e$
-
bash_shell_e$ echo $?
-
0
嗯哼?返回1
,這個(gè)引起了我的注意,證明這條命令執(zhí)行的返回是失敗的。 回頭再看看腳本的開始,我習(xí)慣上是寫
-
#! /bin/bash -e
至于為啥帶上-e
,以前壓根就沒去考慮過,反正看到linux下的好多系統(tǒng)腳本就是這樣寫的,咱這樣是像標(biāo)準(zhǔn)看齊,沒想到還搞出問題了。
2.4 -e究竟是什么含義?
通過查了一些資料,發(fā)現(xiàn)這個(gè)-e
不簡單,它可以對每一條執(zhí)行的shell腳本,自動(dòng)判斷其是否執(zhí)行成功,如果執(zhí)行失敗
,就立即退出整個(gè)腳本的執(zhí)行。 用代碼來體現(xiàn)就是,如果不加-e
,你需要對一個(gè)命令的執(zhí)行結(jié)果判斷,就應(yīng)該這樣:
-
excute_shell_cmd
-
if [ $? != 0 ]; then
-
exit 1
-
fi
而有了-e
,就只有這樣:
-
excute_shell_cmd
看,是不是大大簡潔了腳本,而不會(huì)出現(xiàn)滿屏的if-fi
。 但是這個(gè)帶來的最大問題就是,你可能不知道哪條語句就退出了,應(yīng)該這里退出腳本執(zhí)行的時(shí)候,沒有任何輸出提示,就好像我的案例場景一樣。
2.4 解決辦法1
既然知道是-e
選項(xiàng)引起的,我去掉試試看:
-
#! /bin/bash
-
function get_os()
-
{
-
echo "begin to get OS ..."
-
os=`uname -a | grep Darwin`
-
if [ "$os" != "" ]; then
-
host_os_name=OSX
-
else
-
os=`uname -a | grep x86_64`
-
if [ "$os" != "" ]; then
-
host_os_name=Linux64
-
else
-
host_os_name=Linux32
-
fi
-
fi
-
echo "get OS name: $host_os_name"
-
}
-
function do_other_things()
-
{
-
echo "do other things ..."
-
}
-
get_os
-
do_other_things
-
exit 0
執(zhí)行一下:
-
bash_shell_e$ ./test_shell.sh
-
begin to get OS ...
-
get OS name: Linux64
-
do other things ...
得到了正確的結(jié)果,在其他平臺(tái)上,也得到了正確的結(jié)果。
2.5 解決辦法2
但是,如果我不想去掉-e
呢,有沒有什么辦法? 經(jīng)過一番調(diào)試,我發(fā)現(xiàn)這樣是可以的:
-
#! /bin/bash -e
-
function get_os()
-
{
-
echo "begin to get OS ..."
-
osx_name=Darwin
-
linux64_name=x86_64
-
if [ "`uname -a | grep $osx_name`" != "" ]; then
-
host_os_name=OSX
-
elif [ "`uname -a | grep $linux64_name`" != "" ]; then
-
host_os_name=Linux64
-
else
-
host_os_name=Linux32
-
fi
-
echo "get OS name: $host_os_name"
-
}
-
function do_other_things()
-
{
-
echo "do other things ..."
-
}
-
get_os
-
do_other_things
-
exit 0
輸出結(jié)果如下:
-
bash_shell_e$ ./test_shell_ok.sh
-
begin to get OS ...
-
get OS name: Linux64
-
do other things ...
這里的區(qū)別在于,直接把uname-a|grepDarwin
的執(zhí)行結(jié)果參與if
判斷,而不是用一個(gè)變量去接收返回;這樣居然就通過了。
2.6 擴(kuò)展延伸
有沒有更好的方法調(diào)試shell腳本呢?而不是滿屏的echo
? 這個(gè),下次我再發(fā)文介紹些高階手段吧,敬請期待。
3 更多分享
架構(gòu)師李肯
一個(gè)專注于嵌入式IoT領(lǐng)域的架構(gòu)師。有著近10年的嵌入式一線開發(fā)經(jīng)驗(yàn),深耕IoT領(lǐng)域多年,熟知IoT領(lǐng)域的業(yè)務(wù)發(fā)展,深度掌握IoT領(lǐng)域的相關(guān)技術(shù)棧,包括但不限于主流RTOS內(nèi)核的實(shí)現(xiàn)及其移植、硬件驅(qū)動(dòng)移植開發(fā)、網(wǎng)絡(luò)通訊協(xié)議開發(fā)、編譯構(gòu)建原理及其實(shí)現(xiàn)、底層匯編及編譯原理、編譯優(yōu)化及代碼重構(gòu)、主流IoT云平臺(tái)的對接、嵌入式IoT系統(tǒng)的架構(gòu)設(shè)計(jì)等等。擁有多項(xiàng)IoT領(lǐng)域的發(fā)明專利,熱衷于技術(shù)分享,有多年撰寫技術(shù)博客的經(jīng)驗(yàn)積累,連續(xù)多月獲得RT-Thread官方技術(shù)社區(qū)原創(chuàng)技術(shù)博文優(yōu)秀獎(jiǎng),榮獲CSDN博客專家、CSDN物聯(lián)網(wǎng)領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、2021年度CSDN&RT-Thread技術(shù)社區(qū)之星、RT-Thread官方嵌入式開源社區(qū)認(rèn)證專家、RT-Thread 2021年度論壇之星TOP4、華為云云享專家(嵌入式物聯(lián)網(wǎng)架構(gòu)設(shè)計(jì)師)等榮譽(yù)。堅(jiān)信【知識(shí)改變命運(yùn),技術(shù)改變世界】!
本項(xiàng)目的所有測試代碼和編譯腳本,均可以在我的github倉庫01workstation中找到。
歡迎關(guān)注我的github倉庫01workstation,日常分享一些開發(fā)筆記和項(xiàng)目實(shí)戰(zhàn),歡迎指正問題。
同時(shí)也非常歡迎關(guān)注我的專欄,有問題的話,可以跟我討論,知無不答,謝謝大家。
-
Shell
+關(guān)注
關(guān)注
1文章
368瀏覽量
23549 -
腳本
+關(guān)注
關(guān)注
1文章
395瀏覽量
15055 -
Bash
+關(guān)注
關(guān)注
0文章
57瀏覽量
10260 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1321瀏覽量
40845
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
如何將RT-Thread移植到NXP MCUXPressoIDE上

RT-Thread上CAN實(shí)踐

開源共生 商業(yè)共贏 | RT-Thread 2024開發(fā)者大會(huì)報(bào)名啟動(dòng)!

【成都】9月21日RT-Thread巡回線下培訓(xùn)-OpenMV機(jī)器視覺

【大連】9月7日RT-Thread巡回線下培訓(xùn)-OpenMV機(jī)器視覺

2024 RT-Thread全球巡回 線下培訓(xùn)火熱來襲!

RT-Thread 新里程碑達(dá)成——GitHub Star 破萬!

6月6日杭州站RT-Thread線下workshop,探索RT-Thread混合部署新模式!

2024 RT-Thread 全球技術(shù)大會(huì)演講議程發(fā)布!

新書發(fā)布——《實(shí)時(shí)操作系統(tǒng)應(yīng)用技術(shù):RT-Thread與ARM編程實(shí)踐》

RT-Thread混合部署Workshop北京站來啦!

4月25日北京站RT-Thread線下workshop,探索RT-Thread混合部署新模式

4月10日深圳場RT-Thread線下workshop,探索RT-Thread混合部署新模式!

4月10日深圳場RT-Thread線下workshop,探索RT-Thread混合部署新模式!

恩智浦半導(dǎo)體正式加入RT-Thread全球合作伙伴計(jì)劃!

評(píng)論