ubuntu下第一個的shell腳本"細胞分裂"
關于終端輸入執(zhí)行的一般邏輯,貌似如此:
(這些邏輯對特殊的例如if之類的不管用)
字符串1 空格 字符串2 空格 字符串3.....
字符串1被識別成指令,后面是傳入?yún)?shù),它們間用空格隔開。
如果是這樣 空格xN?字符串1 空格 字符串2 空格 字符串3.....
字符串1依舊是命令,后面是參數(shù)。


字符串1 空格 $字符串2 空格 字符串3.....
字符串1是命令,字符串2前面加上$,如果某個變量名(變量名必須是英文)等于"字符串2",那么傳入?yún)?shù)1是這個變量的值。

字符串1 空格 $(字符串2) 空格 字符串3.....
傳入?yún)?shù)1是指令"字符串2"的輸出值。(括號內(nèi)必須是指令,否則會出錯)

字符串1 ; 字符串2
如果兩個字符用分號隔開如上,那么字符串1和字符串2都是指令

按如上邏輯來解釋下面的命令

音樂/CloudMusic下不存在文件,所以指令ls的輸出結(jié)果必然是空字符串。
-z是"["指令的參數(shù),用來判斷字符串長度是否為0,字符串長度為0,則整個指令輸出1,否則為0。
先看看關于if語句的邏輯,貌似是這樣:
if 指令
then
? 指令1
else
? 指令0
fi??
關鍵字if加空格隔開后跟著一個指令,如果這個指令輸出1就執(zhí)行then命令下的指令1,否則就執(zhí)行else指令下的指令0,fi是if語句結(jié)束指令,fi實際上就是if反過來寫,case語句的結(jié)束指令esac也是case反過來寫。
根據(jù)大神的文章(詳見https://www.cnblogs.com/include/archive/2011/12/09/2307905.html)
"["是一個命令,[...]里面的內(nèi)容是命令的參數(shù),"]"應該是命令的結(jié)束符號(我猜的)

第一段判斷邏輯:
if和[...]用空格隔開,if是指令?"["是指令,[...]里的內(nèi)容是參數(shù),"["得與參數(shù)用空格隔開,參數(shù)之間也得用空格隔開,否則會發(fā)生不可名狀的錯誤。
[...]內(nèi)的參數(shù)"ls"是字符串,它不為空,所以輸出結(jié)果為
Exist(存在)
第二段判斷邏輯:
$(ls)是指令ls的輸出結(jié)果,它是空,所以輸出結(jié)果為
Null(空)
第三段判斷邏輯:
在判斷前,我們在工作目錄下創(chuàng)建了一個文件
?$(ls)是指令ls的輸出結(jié)果,它現(xiàn)在不為空,所以輸出結(jié)果為
?Exist(存在)
關于shell腳本與shell指令:
shell翻譯作殼、貝殼等,shell是用戶與內(nèi)核進行交互的接口
pwd、vi、gcc、sudo、mv、echo等都是shell指令
我們可以擴充shell,獲得更多的shell指令。
shell腳本實際上就是有序地執(zhí)行一系列shell指令,它本身也算是shell指令
使用shell指令echo在終端打印"師姐,你好!":
在安裝系統(tǒng)的時候我們選擇了簡體中文語言,一般來說安裝程序會為我們安裝中文輸入法,我們只需要按win+空格鍵就可以切換輸入法了!
echo "師姐,你好!"

使用shell指令創(chuàng)建變量a并為其賦值10:
直接賦值:
a=10給a賦值10
$a?讀取變量a的值

在賦值時不能隨意加入空格,例如a =10,按照最開始的說法,a是指令,=10是指令a的傳參
read指令賦值:
read -p "請輸入一個值" a

命令的結(jié)果作為變量的值:
a=$(ls -l | grep ^- |wc -l')a的值為工作目錄下普通文件的個數(shù)

其他幾種賦值方式就不討論了,因為我不會
使用shell指令cp將工作目錄下的文件HW復制到其子目錄文檔下并命名為HWcp:
cp HW 文檔/HWcp


Linux系統(tǒng)中的文件類型及其標識符
普通文件,標識符:-
目錄文件,標識符:d (Directory)
符號鏈接文件,標識符:l (Link)
塊文件,標識符:b (Block)
管道文件,標識符:p (Pipe)
套間字,標識符:s (Socket)
使用shell指令ls -l (list -long)顯示工作目錄下的詳細信息:

一行表示一個文件,某行首字符是此行文件的文件類型標識符
使用shell指令grep來篩選:
來自CSDN大神https://blog.csdn.net/chen1415886044/article/details/107116370

grep 師姐 師姐好.c 在師姐好.c文件中尋找含有子串"師姐"的所有行并輸出到終端上:


grep ^# 師姐好.c?在師姐好.c文件中搜索行首首字符為#的行并輸出到終端上

shell指令中的符號|:
|意思為將前一個指令的輸出參數(shù)作為下一個指令的輸入?yún)?shù),例如
ls -l | grep ^-? 將ls -l輸出作為grep指令的第二個傳參(第一個參數(shù)是^-),此指令作用是獲得工作目錄下普通文件的信息
ls -l | grep ^- | wc -l 此指令作用是統(tǒng)計工作目錄下普通文件的數(shù)量



更多符號的含義:來自CSDN大神https://blog.csdn.net/weixin_43972437/article/details/112606169

編寫第一個shell腳本:
shell腳本的后綴名為.sh,我們使用vim編輯器創(chuàng)建一個名為cell0.sh的shell腳本,

第一行表示此腳本shell指令的路徑

我們寫下如上圖的指令,$0的值是腳本本身,$1是腳本傳入的第一個參數(shù),$2是第二個........
$@的作用是顯示所有傳參
我們規(guī)定所有的細胞腳本的命名規(guī)則為:"cell"+"某個數(shù)字"
所以ls -l | grep cell |wc -l指令能輸出工作目錄下的細胞腳本總數(shù)
我們用變量N來存儲工作目錄下的細胞腳本數(shù),然后保存先試著運行一下腳本

當然這時候運行腳本也可能會提示和權(quán)限有關的錯誤,這可能是因為我們沒有這個文件的執(zhí)行權(quán)限,所以它現(xiàn)在對于我們來說還不是可執(zhí)行文件,我們用指令sudo chmod 700給用戶賦予此文件的所有權(quán)限并關閉G(Group,意為自己的用戶組)組和O(Other,翻譯為其他)用戶的權(quán)限。(注意shell腳本權(quán)限,即便腳本不具有破壞性,我們也不希望任何人都有執(zhí)行它的權(quán)限)
再寫一個交互指令,用read指令來讀取用戶的選擇,并使用if語句來輸出用戶的選擇

文章最開始已經(jīng)討論過if命令了,注意空格,==也是傳參,也得用空格隔開,否則將會發(fā)生不可名狀的錯誤

OK,寫到這里,可以將這些代碼都刪了(除了統(tǒng)計細胞個數(shù)的代碼),這些只是用來練練手,熟悉一下shell語法用的。
接下來來實現(xiàn)我們的邏輯吧!
首先寫兩個細胞分裂的邏輯,第一個細胞分裂是自分裂,也就是當前細胞腳本自身是否復制一份,我們用傳入?yún)?shù)1來控制,傳入"y"表示啟用自分裂,否則沒有動作,第二個細胞分裂是控制當前目錄下所有細胞的自分裂,傳入"y"表示啟動所有細胞自分裂。
這兩個邏輯都很簡單,自分裂邏輯中還加入了數(shù)量限制

我們執(zhí)行0號細胞腳本,給它傳入 n y,首先它會統(tǒng)計當前目錄下細胞個數(shù),然后用for語句將這些細胞都啟動自分裂也就是 "./cell$i.sh",這樣做有一個好處,那就是新分裂的細胞不會被執(zhí)行,同時剛執(zhí)行0號細胞腳本時,它不會自分裂,它會在啟動全局分裂時和工作目錄下的其他細胞一起自分裂。
這樣我們可以控制單個細胞的分裂和全部細胞的分裂。由于這樣的邏輯依賴于細胞腳本的名字(主要是索引),如果在分類的過程中,用戶將某些細胞刪除了,此時再進行全局分裂可能出現(xiàn)一點小問題,所以我又加入了重排列函數(shù),在執(zhí)行自分裂前先重排列,我用第三個傳參控制是否執(zhí)行重排列。

將4、5號細胞移動到別的目錄后,此時剩下6個細胞,再次執(zhí)行全局分裂

分裂完成后有12個細胞,由于我加入了重排列邏輯,所以4、5又出現(xiàn)了,他們是由6、7號變的,重排列的邏輯也很簡單,對!就是聰明的你所想的那樣!
也可以加入定時邏輯,讓分裂自動執(zhí)行、讓它具有周期性。
最好再加入劊子手細胞,一鍵即可殺死所有細胞,當然這里的空白太小了,我已經(jīng)寫不下了,到此為止!