— 作者 謝恩銘 轉載請註明出處
內容簡介
- 第三部分第五課:延時執行,唯慢不破
- 第三部分第六課預告:第三部分測驗題
延時執行,唯慢不破
上一課 Linux探索之旅 | 第三部分第四課:後臺執行及合併多個終端 中,我們學習了後臺程式以及如何在一個終端裡開啟多個虛擬終端。
到目前為止,我們所執行的命令都是立即執行的。也就是我們按下Enter鍵的那一刻,命令就開始執行了。
其實,在Linux中,命令還可以延時執行。這一課我們就來學習幾個命令,可以幫助我們“稍後”執行程式。比如我們即將學習到的crontab命令。
雖說“天下武功,唯快不破”。
但有時,延時執行命令是很有必要的。
這一課新學的命令都涉及到時間的觀念,所以我們先來學習有關係統時間的規格。
date命令:調節時間
早期的課程中,我們已經介紹過date命令了。但那時我們只學習了date命令的最基本用法:輸出當前時間。
date命令的基本用法就是輸入date,然後回車:
輸出資訊的含義我們以前解釋過了,再複習一次吧。從左到右依次是:
-
Sat:Saturday的縮寫,表示“禮拜六”。
-
Sep:September的縮寫,表示“九月”。
-
19:19日,也就是9月19日。
-
23:07:41:23點07分41秒。
-
CEST:所在時區。CEST是Central European Summer Time的縮寫,表示《歐洲中部夏令時間》,比世界標準時間(UTC)早兩個小時的時區名稱。
-
2015:2015年。
定製date的輸出
date命令其實挺強大的,它不僅可以輸出當前時間,而且如果用man date來檢視date命令的手冊,就可以發現我們還可以自定義它的輸出:可以選擇輸出哪部分資訊,輸出格式以及輸出的順序。
為了自定義date命令的輸出,我們需要用到+號,後接其他的符號,表示不同的定製部分,這些資訊最好都寫在雙引號間。我們來看幾個例子,你就會使用了:
date "+%H"複製程式碼
可以看到,輸出是 00。
表示當前的小時數是00,因為H是hour的首字母,表示《小時》。
再來一個複雜點的:
date "+%H:%M:%S"複製程式碼
可以看到,在剛才+%H的基礎上,新增了%M和%S,分別表示分鐘數和秒數。因為M是英語minute的首字母,表示《分鐘》;S是英語second的首字母,表示《秒》。
所以以上命令用於顯示當前的小時數,分鐘數和秒數。我們用自定義的冒號來分隔三個部分資訊。
當然了,我們也可以自定義其他的分隔字元,例如:
date "+%H時%M分%S秒"複製程式碼
可以看到,經過定製,我們的顯示變得更加人性化了。只有緊跟%號之後的符號會被解析,而其他如《時,分,秒》等資訊則原樣輸出。
那小編怎麼知道%M就是表示分鐘呢?因為小編看date命令的手冊了啊。
因此,我也知道如何顯示年份:
date "+現在是%Y年"複製程式碼
還有其他各種輸出的定製,好好看手冊,你可以自由發揮。
用date修改系統時間
date命令還可以修改系統時間。是的,你沒有看錯。
修改系統時間需要使用root身份,因此我們可以這樣做:
sudo date 12101250複製程式碼
date命令後接的引數可以是多種形式的,此處的12101250表示《12月10日12點50分》,沒有指定年份和秒數,所以年份和秒數不變。
再次用date命令輸出當前系統時間,可以看到已經改為了
Thu Dec 10 12:50:02 CET 2015複製程式碼
表示《星期二 十二月 10日 12點50分02秒 歐洲中部時間 2015年》。
你可以手動再修改回原來的系統時間。
當然,你也可以設定系統時間和網路的時間同步。
在System->Administration->Time and Date裡,選擇《Keep synchronized with Internet servers》,表示《與網際網路的伺服器同步》(預設是手動修改系統時間的)。然後在下面的Time servers裡可以選擇你想要同步的時間伺服器,小編選擇的是法國的。它會讓你安裝ntp這個程式,選擇確定安裝。
之後,Linux系統就會和指定的時間伺服器同步了。就不用擔心時間不對了,當然,需要在聯網的情況下才可以。
at命令:延時執行一個程式
你想要延時執行一個程式(所有的命令說到底都是程式)嗎?沒問題。我們可以用at命令來設定一個程式的執行時間。
at是英語《在…時刻》的意思。
注意:at命令只能讓程式執行一次。
如果你要定時重複執行程式,那就要用crontab命令,本課的最後一節我們會學到。
at命令有幾種用法,我們先來看第一種:
在指定時刻執行程式
在這種用法下,at命令的使用順序如下:
-
先用at命令後接想要程式執行的確定時刻
-
再輸入你想要在以上指定時刻執行的命令
例如:
at 17:12複製程式碼
回車,
終端會顯示at>,提示你輸入要在17點12分執行的命令。
我們可以輸入
touch file.txt複製程式碼
表示我們想要在17點12分建立一個檔案,名叫file.txt。
然後,回車。at命令會繼續顯示at>,提示你輸入在指定時刻想要執行的其他命令。你可以繼續輸入。但你也可以就此打住。
那麼怎麼結束輸入退出at命令呢?可以使用Ctrl + D組合鍵,at會顯示
job 1 at Sun Sep 20 17:12:00 2015複製程式碼
上面這句話表示:
-
job:英語《工作,任務》的意思,表示建立了一個任務。
-
1:是job的編號。表示第1號任務。
-
at:”在…時刻”,也正是at命令的作用所在。
-
Sun:Sunday的縮寫。是英語《星期日》的意思。
-
Sep:September,英語《九月》的意思。
-
20:20日。9月20日。
-
17:12:00:命令執行的時刻。17點12分00秒,也就是我們用 at 17:12 指定的時間。
-
2015:2015年。
之後,到了17點12分,就會建立file.txt這個檔案了。
如果說我們不想要在今天的17點12分執行指定命令,而想要在明天的17點12分執行,怎麼做呢?可以這樣:
at 17:12 tomorrow複製程式碼
tomorrow是英語《明天》的意思。
那我要在2015年12月10日的17點12分執行呢?
at 17:12 12/10/15複製程式碼
日期的格式是美國日期的格式,所以是 12/10/15,依次是《月/日/年》。
在指定間隔之後執行程式
at還有第二種用法,就是在指定時間間隔之後執行程式。
例如,我要在10分鐘之後執行指定程式:
at now +10 minutes複製程式碼
now表示《現在》,+10 minutes表示《10分鐘之後》,所以就是《現在開始的10分鐘之後執行》。
這裡我隨便寫了一個命令:
cp file.txt file_copy.txt複製程式碼
所以,job 2被建立了,就是在現在開始的10分鐘會執行《拷貝file.txt檔案到file_copy.txt》。
當然了,不止minutes這個關鍵字可以使用,我們列出幾乎所有可以使用的關鍵字:
-
minutes:表示《分鐘》。
-
hours:表示《小時》。
-
days:表示《天》。
-
weeks:表示《星期》。
-
months:表示《月》。
-
years:表示《年》。
例如:
at now +7 weeks複製程式碼
表示在距今7個星期之後執行。
atq和atrm命令:列出和刪除正在等待執行的at任務
每次我們用at命令指定延時執行的命令,at都會為其分配一個job編號,比如我們上面的兩個例子,分別被分配了1和2的編號。1號是touch file.txt,2號是cp file.txt file_copy.txt。
atq命令可以列出正等待執行的at任務。q是英語queue的首字母,queue表示《佇列》,會列出at命令的任務佇列。
atrm命令可以刪除正在等待執行的at任務。rm是英語remove的首字母,remove表示《刪除》。後接at任務的編號。例如1和2這樣的編號。
我們來實際操作一下:
可以看到,我們用atq命令列出了at任務,有兩個,就是我們上面設定的兩個延時任務,分別會在17點12分和1點38分執行。
然後我們用atrmyici刪除了這兩個任務,因此就不會執行任何任務了。
sleep命令:休息一會
其實,我們可以用分號隔開多個命令,使之一個接一個執行。跟之前的管道不一樣,管道是前一個命令的輸出作為後一個命令的輸入。用分號隔開的各個命令並沒有關聯。例如:
touch file.txt ; rm file.txt複製程式碼
上面用分號隔開的兩句命令的作用:建立file.txt檔案,然後刪除之。
我們在兩句命令之前可以插入一定的暫停等待時間,用sleep命令。
sleep是英語“睡覺,睡眠”的意思。
touch file.txt ; sleep 10 ; rm file.txt複製程式碼
上面的三句命令分別表示:
-
touch file.txt :建立檔案file.txt
-
sleep 10 :暫停10秒
-
rm file.txt :刪除file.txt
預設地,sleep後面的數值表示秒數。但我們也可以指定其表示分鐘或小時或天:
-
m:minute的縮寫,表示《分鐘》。
-
h:hour的縮寫,表示《小時》。
-
d:day的縮寫,表示《天》。
例如:
touch file.txt ; sleep 15m ; rm file.txt複製程式碼
上面的三句命令會依次執行:建立file.txt檔案,暫停15分鐘,刪除file.txt檔案。
&& 和 || :真真假假
上面我們講了sleep命令的用法,也提到了分號的作用:可以用於分隔多個命令,使多個命令可以寫在一行裡,然後依次執行,分號前的一個命令執行完,就會執行分號後的一個命令。但是分號前的命令執行成功與否並不會影響後面的命令。不管如何,分號前後的命令都會執行。
我們來學習兩個很有用的符號:&& 和 ||
這兩個在程式語言裡一般稱為邏輯與和邏輯或符號,在命令列裡又會起到什麼作用呢?
&&及||和分號一樣,用於分隔兩個命令,使得命令依次執行,貌似和分號類似,但是有區別。
簡單說來,就是:
-
&&:分號前的命令執行成功,才會執行後面的命令。
-
||:分號前的命令執行失敗,才會執行後面的命令。
-
分號:不論分號前的命令執行成功與否,都執行分號後的命令。前後命令之間沒有相關性。
這三個符號非常有用,可以提高我們命令列的效率和豐富程度。
crontab命令:定時執行程式
crontab命令是Linux中很常用也很強大的一個命令。它使我們可以定時執行程式。
前面我們學過的at命令,只能執行某個(或某幾個)命令一次。
但是crontab卻可以重複執行命令。例如:每小時,每分鐘,每天,每星期,等等。
安裝crontab
一般來說,Ubuntu下是預設安裝了crontab程式的。不過有的Linux發行版可能沒裝crontab。
crontab的安裝,舉yum系列和apt-get系列兩個例子來看看吧:
在CentOS(Fedora下也類似)中安裝Crontab
sudo yum install vixie-cron crontabs #安裝Crontab
chkconfig crond on #設為開機自啟動
service crond start #啟動複製程式碼
在Debian(Ubuntu是Debian一族的)中安裝Crontab
sudo apt-get install cron # 大部分情況下Debian都已安裝
service cron restart 或者 restart cron # 重啟crontab複製程式碼
Ubuntu下啟動,停止和重啟動crontab:
service cron start
service cron stop
service cron restart複製程式碼
前期配置工作
在我們學習crontab之前,我們需要先做一些配置。我們來修改 .bashrc 這個檔案,之前的課程我們已經學習過了,這是bash這個shell(簡單地說就是控制我們當前終端的程式)的配置檔案。
也沒什麼太大的修改,就是想讓Nano這個文字編輯器成為我們預設的文字編輯器。因為Ubuntu系統一般預設的文字編輯器是vi,而vi是比較難的文字編輯器,我們之後的課程會專門學習vi和vim。我們目前只會Nano這個文字編輯器,所以暫時不去碰vi。
我們要做的就是把這一句話加入 .bashrc 檔案:
export EDITOR=nano複製程式碼
用我們學過的重定向的知識,我們可以這樣做:
echo "export EDITOR=nano" >> ~/.bashrc複製程式碼
這樣,就把export EDITOR=nano這句話追加到了家目錄下的.bashrc檔案最後。
可以看到,export EDITOR=nano這句話被追加到了.bashrc檔案的末尾。editor是英語《編輯器》的意思。
執行以下命令使改動立即生效,不然須要重開一個終端或者重新登入才能生效。
source ~/.bashrc複製程式碼
ok,準備工作做好了,我們來認識crontab吧。
crontab,是什麼呢?
crontab其實是一個命令,用來讀取和修改名為crontab的檔案。這個crontab檔案包含了你要定時執行的程式列表,也包含了執行的時刻。
實際上,有兩個命令,一個叫crontab,一個叫cron。crontab用於修改crontab檔案,cron用於實際執行定時的程式。
crontab命令如何使用呢?
有三個引數要了解:
-
-e:修改crontab檔案。
-
-l:顯示crontab檔案。
-
-r:刪除crontab檔案
我們首先嚐試顯示crontab檔案:
crontab -l複製程式碼
可以看到,顯示了《no crontab for oscar》,表示《使用者oscar暫時沒有任何crontab檔案》。
其實,每個使用者有自己的crontab檔案。比如root使用者也有自己的crontab檔案:
好吧,既然暫時我們的使用者還沒有crontab檔案,那麼我們就來建立咯。
可以用
crontab -e複製程式碼
命令,之前我們說過crontab -e用於修改crontab檔案,那既然檔案不存在,就會新建一個,用什麼編輯器編輯此crontab檔案呢?就是用我們指定的Nano文字編輯器。
如果你之前正確配置了.bashrc檔案,也就是在檔案最後新增了export EDITOR=nano 這一行的話,那麼執行crontab -e命令之後,會用nano編輯器來開啟你的crontab檔案。如果沒有正確配置.bashrc,那麼將會由預設的vi編輯器來開啟。但是暫時我們還沒有講過vi怎麼用,所以你可以退出vi。輸入q,然後回車。
再重新配置,直到執行crontab -e命令,終端用nano開啟crontab檔案為止。
當然了,如果你已經會用vi或vim或emacs,那麼就不必配置用nano了。
修改crontab檔案
暫時,我們的crontab檔案剛被建立,所以沒什麼實際內容,如下圖:
可以看到,我們的crontab檔案位於 /tmp/crontab.5gvGPg/目錄中。(我承認,crontab.5gvGPg這個名字很奇怪。)
crontab檔案中只有一句話:
# m h dom mon dow command複製程式碼
注意,這句話是以#開頭的,因此是註釋。
其實,這句話給出了crontab中的每行指令的書寫格式:
-
m:minute。表示《分鐘》。
-
h:hour。表示《小時》。
-
dom:day of month。表示《一個月的哪一天》。
-
mon:month。表示《月份》。
-
dow:day of week。表示《星期幾》。
-
command:需要定時執行的命令。
用下圖表述:
所以每一行的寫法很清楚:你須要先寫定時是在什麼時候,然後在最後寫上定時執行什麼命令。
理解crontab不是那麼容易,但也沒有很難。我們會用好幾個例子來幫助大家瞭解。
上圖中用X表示的五個區域分別是《分鐘,小時,日,月份,星期幾》,這五個區域要麼用數字加符號填充,要麼寫上一個星號(*),表示任何值。
例如:
我希望每天的17點12分都在我的家目錄下建立file.txt檔案。可以在crontab檔案裡寫入:
12 17 * * * touch /home/oscar/file.txt複製程式碼
12表示分鐘,17表示小時,其他三個區域是*,最後的命令是 touch /home/oscar/file.txt。
路徑最好用絕對路徑,因為你並不能確定cron命令執行這些語句的時候是在哪個目錄。
然後,儲存退出Nano。如果語法正確的話,crontab會顯示:
crontab: installing new crontab複製程式碼
意思是:安裝新的crontab檔案。
現在,既然已經設定好了。那麼file.txt檔案將會在每天的17點12分被建立於/home/oscar這個目錄下(如果file.txt檔案不存在的話)。
我們看幾個例子:
Crontab | 意義 |
---|---|
47 * * * * command | 每個小時的47分都執行command命令,也就是 00點47, 01點47, 02點47, 等等 |
0 0 * * 1 command | 每個禮拜一的凌晨都執行command命令 |
30 5 1-15 * * command | 每個月的1~15日的5點30分都執行command命令 |
0 0 * * 1,3,4 command | 每個禮拜一,禮拜三,禮拜四的凌晨都執行command命令 |
0 */2 * * * command | 每2個小時的整點(0,2,4,6,等等)都執行command命令 |
*/10 * * * 1-5 command | 每個禮拜一到禮拜五的每個10的倍數的分鐘(0,10,20,等等)都執行command命令 |
你可以自己設計出很多很多不同的組合用法,來實現你的定時程式。
crontab -r複製程式碼
用於刪除crontab檔案。
可以看到,我們執行crontab -l,此時我們有一個crontab檔案,顯示的內容就是我們之前用Nano編輯器填寫的。
然後我們用crontab -r來刪除crontab檔案,則再用crontab -l命令時,就顯示《no crontab for oscar》,就是又不存在crontab檔案了,也就沒有定時執行的任務了。
總結
-
date命令可以顯示系統時間,可以按自定義格式顯示,也可以修改系統時間。
-
at命令可以延時執行程式。但是它只能執行一次。
-
分號,&&和||都可以用來連線多個命令:用於依次執行前後命令。
-
sleep命令用於使前後兩個命令執行之間間隔一定時間。
-
crontab用於定時執行程式。例如:每天17點12分,每禮拜二和禮拜三在12點,每個月的7號,等等。我們用crontbab -e來修改crontab程式。
第三部分測驗題預告
今天的課就到這裡,一起加油吧!
下一課我們學習:第三部分測驗題
微信公眾號「程式設計師聯盟」ProgrammerLeague
我是謝恩銘,在巴黎奮鬥的軟體工程師。
我的簡介
我的經歷
熱愛生活,喜歡游泳,略懂烹飪。
人生格言:“向著標杆直跑”