大家好,我是良許。
今天跟大家聊個尷尬的事,大家可以本著看熱鬧不嫌事大的心態來聽我嘮嘮。
經常來我直播間(影片號+抖音)的小夥伴都知道,我最近一直都在直播間手把手現場寫 Shell 指令碼。
就在前天晚上,我寫 Shell 指令碼的時候,不小心把當前目錄下所有指令碼(連同這個指令碼本身)全部刪除了,而且還全程直播了……
這是我做直播到現在最大的一次直播事故啊。。
這個指令碼的需求是這樣的:把當前目錄(包含子目錄)下所有字尾為 ".sh" 的檔案字尾變更為 ".shell",之後刪除每個檔案的第二行。
我先把正確的指令碼貼出來給各位看官看看:
#!/bin/bash
ALL_SH_FILE=$(find . -type f -name "*.sh")
for file in ${ALL_SH_FILE[*]}
do
# filename=${file%.sh*}
filename=$(echo $file | awk -F'.sh' '{print $1}')
new_filename="${filename}.shell"
mv "$file" "$new_filename"
sed -i '2d' "$new_filename"
done
這個需求看起來蠻多的,但仔細拆解一下,其實要求就下面這幾個:
- 找到當前目錄下所有以
.sh
結尾的檔案; - 遍歷這些檔案,將字尾改為
.shell
; - 刪除每個檔案的第二行。
我們在寫程式碼的時候,一定不要著急動手,先拆解一下,這樣寫起來就容易很多。下面就逐一解決這些需求。
需求1:找到當前目錄下所有以 .sh
結尾的檔案
找檔案,很容易就想到 find
命令。
與 find
命令結合的選項無非就是:-type
、 -name
、 -size
、 -mtime
,其它的相對而言用得比較少。在這裡,很明顯使用 -type
和 -name
。
要是連 find
命令都用不熟的小夥伴,趕緊拍一拍文末的命令課。
$ find . -type f -name "*.sh"
需求2:遍歷這些檔案,將字尾改為 .shell
遍歷檔案問題也不大,就是使用 for xxx in yyy
這種格式,這裡的 yyy 就是我們上面找到的全部字尾 .sh
檔案。
然後就是改字尾,肯定要使用到 mv
命令了。我們一般是這樣修改檔名的:
$ mv old_filename new_filename
這裡 old_filename 好辦,就是我們一個個遍歷的檔名。關鍵是 new_filename ,怎麼拼湊出我們需求的檔名。
仔細分析一下,就是將 old_filename 裡的 .sh
字尾去掉,再拼上 .shell
字尾。
去掉 .sh
字尾的方法有很多,這裡介紹兩個:
- 字串切片
$ filename=${file%.sh*}
- 利用
awk
命令切片
這裡用到一個很巧妙的方法,就是把 .sh
視為分隔符,然後提取的第一列就是檔名了。
$ filename=$(echo $file | awk -F'.sh' '{print $1}')
這樣我們就得到了沒有 .sh
字尾的檔名了,我們再拼上 .shell
字尾就行了。
$ new_filename="${filename}.shell"
然後,我們再使用 mv
命令修改一下檔名就大功告成了。
需求3:刪除每個檔案的第二行
這個需求毫無難度,sed
一下就行了。所以說,文字處理三劍客在 Shell 指令碼里真的是無處不在,大家一定要好好掌握。
$ sed -i '2d' "$new_filename"
三個需求都實現之後,我們再寫起程式碼來就沒啥難度了。
直播中,為了演示方便,我建立了三個 .sh
字尾檔案。
然後,我一頓操作猛如虎,很快就寫好了程式碼。
當我雄心壯志敲下Enter鍵執行指令碼,打算在直播間秀一把時,得到了這樣的結果:
完了,怎麼結果跟我預想的不一樣?
完了,我的那幾個 .sh
檔案呢??
完了,我的指令碼本身去哪了???
完了,難道我刪庫了??
完了,兩個直播間加起來有 400 多號人正盯著我看呢。。
完了完了,翻車了,出醜了,尷尬了。。
你們看我我上面的操作記錄就可以看到此時的我內心有多慌亂。。
但我已經連續直播 5 個多月了,最高的時候有 3300+ 人線上,早已經身經百戰,什麼大風大浪沒見過?
於是我迅速調整好心態,努力回想是什麼原因導致了這次翻車事故。
但是指令碼已經沒了,只剩下孤零零的一個 new_filename
這個檔案,想複查程式碼都沒辦法。
我努力回想,怎麼也想不到到底哪裡出錯了。
這個new_filename
也一直在那邊,彷彿瞪著眼睛看著我,也在嘲笑我。
今天在寫這篇文章的時候,突然想到,所有的 .sh
檔案都不見了,突然冒出了一個 new_filename
檔案,或許可以從它下手。
再回看一眼程式碼,我恍然大悟!!
我特麼在 mv
那裡,new_filename
變數前忘記寫了 $
符號了!!然後就變成了這樣:
$ mv "$file" "new_filename"
這下好了,所有的 .sh
檔案全部重新命名成了 new_filename 了!
怪不得所有的 .sh
檔案全部離奇失蹤。。
我再寫一遍程式碼,然後手動把 new_filename 前面的 $ 去掉,成功復現了昨晚的現象。
終於是真相大白了……
所以啊,寫程式碼一定要慎重再慎重,小心再小心,否則的話就有可能出現這種意想不到的結果。
實際上,之前在公司上班的時候,我有一次誤操作,把我自己的程式碼全部刪除了。。還好有 Git ,否則我估計就要掃地出門了。。
Linux 下,不僅 rm
命令很危險,mv
和 cp
命令同樣也沒你想得那麼安分,一不小心就可能把檔案移沒了或者覆蓋了。
所以大家在使用這三個命令的時候,一定要再三確認之後再敲Enter鍵,否則可能連哭都來不及了。
大家一起引以為戒。
PS :直播中有個小插曲。有個黑粉看到我出錯了,開始各種挖苦嘲諷。好在直播間大家都比較友好,紛紛幫我懟回去。
寫程式碼哪可能不會出錯?你要是那麼厲害,也沒空來我直播間看我寫程式碼。程式設計師本來就是邊寫程式碼邊除錯的,能夠一次成功的,估計沒幾個人能做到。
而且這種人,大機率在現實中也是唯唯諾諾,在領導面前卑躬屈膝,薪資不過萬之人。只有在網路上去噴別人,才可以找到一點存在感。
呵呵。
學習程式設計,千萬不要急於求成,一定要多讀一些經典書籍,多看原始碼,多下苦功夫去死磕程式碼,這樣技術才能長進。給大家分享一些程式設計師必讀經典書籍,一定要多讀幾遍:
免費送給大家,只求大家金指給我點個贊!
有收穫?希望老鐵們來個三連擊,給更多的人看到這篇文章
推薦閱讀:
歡迎關注我的部落格:良許Linux教程網,滿滿都是乾貨!