Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

程式設計師聯盟發表於2019-02-14

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

-- 作者 謝恩銘 轉載請註明出處

內容簡介


  1. 第三部分第五課:延時執行,唯慢不破
  2. 第三部分第六課預告:第三部分測驗題

延時執行,唯慢不破


上一課 Linux探索之旅 | 第三部分第四課:後臺執行及合併多個終端 中,我們學習了後臺程式以及如何在一個終端裡開啟多個虛擬終端。

到目前為止,我們所執行的命令都是立即執行的。也就是我們按下Enter鍵的那一刻,命令就開始執行了。

其實,在Linux中,命令還可以延時執行。這一課我們就來學習幾個命令,可以幫助我們“稍後”執行程式。比如我們即將學習到的crontab命令。

雖說“天下武功,唯快不破”。
但有時,延時執行命令是很有必要的。

這一課新學的命令都涉及到時間的觀念,所以我們先來學習有關係統時間的規格。

date命令:調節時間


早期的課程中,我們已經介紹過date命令了。但那時我們只學習了date命令的最基本用法:輸出當前時間。

date命令的基本用法就是輸入date,然後回車:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

輸出資訊的含義我們以前解釋過了,再複習一次吧。從左到右依次是:

  • 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"複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,輸出是 00。

表示當前的小時數是00,因為H是hour的首字母,表示《小時》。

再來一個複雜點的:

date "+%H:%M:%S"複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,在剛才+%H的基礎上,新增了%M和%S,分別表示分鐘數和秒數。因為M是英語minute的首字母,表示《分鐘》;S是英語second的首字母,表示《秒》。

所以以上命令用於顯示當前的小時數,分鐘數和秒數。我們用自定義的冒號來分隔三個部分資訊。

當然了,我們也可以自定義其他的分隔字元,例如:

date "+%H時%M分%S秒"複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,經過定製,我們的顯示變得更加人性化了。只有緊跟%號之後的符號會被解析,而其他如《時,分,秒》等資訊則原樣輸出。

那小編怎麼知道%M就是表示分鐘呢?因為小編看date命令的手冊了啊。

因此,我也知道如何顯示年份:

date "+現在是%Y年"複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

還有其他各種輸出的定製,好好看手冊,你可以自由發揮。

用date修改系統時間


date命令還可以修改系統時間。是的,你沒有看錯。

修改系統時間需要使用root身份,因此我們可以這樣做:

sudo date 12101250複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

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 探索之旅 | 第三部分第五課:延時執行,唯慢不破

之後,Linux系統就會和指定的時間伺服器同步了。就不用擔心時間不對了,當然,需要在聯網的情況下才可以。

at命令:延時執行一個程式


你想要延時執行一個程式(所有的命令說到底都是程式)嗎?沒問題。我們可以用at命令來設定一個程式的執行時間。

at是英語《在...時刻》的意思。

注意:at命令只能讓程式執行一次。
如果你要定時重複執行程式,那就要用crontab命令,本課的最後一節我們會學到。

at命令有幾種用法,我們先來看第一種:

在指定時刻執行程式


在這種用法下,at命令的使用順序如下:

  1. 先用at命令後接想要程式執行的確定時刻

  2. 再輸入你想要在以上指定時刻執行的命令

例如:

at 17:12複製程式碼

回車,

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

終端會顯示at>,提示你輸入要在17點12分執行的命令。

我們可以輸入

touch file.txt複製程式碼

表示我們想要在17點12分建立一個檔案,名叫file.txt。

然後,回車。at命令會繼續顯示at>,提示你輸入在指定時刻想要執行的其他命令。你可以繼續輸入。但你也可以就此打住。

那麼怎麼結束輸入退出at命令呢?可以使用Ctrl + D組合鍵,at會顯示,表示《End Of Transmission》(表示《傳輸結束》)。然後會列印出一句話:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

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複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

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這樣的編號。

我們來實際操作一下:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,我們用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檔案最後。

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,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複製程式碼

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,顯示了《no crontab for oscar》,表示《使用者oscar暫時沒有任何crontab檔案》。

其實,每個使用者有自己的crontab檔案。比如root使用者也有自己的crontab檔案:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

好吧,既然暫時我們的使用者還沒有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檔案剛被建立,所以沒什麼實際內容,如下圖:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,我們的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:需要定時執行的命令。

用下圖表述:

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

所以每一行的寫法很清楚:你須要先寫定時是在什麼時候,然後在最後寫上定時執行什麼命令。

理解crontab不是那麼容易,但也沒有很難。我們會用好幾個例子來幫助大家瞭解。

上圖中用X表示的五個區域分別是《分鐘,小時,日,月份,星期幾》,這五個區域要麼用數字加符號填充,要麼寫上一個星號(*),表示任何值。

例如:

我希望每天的17點12分都在我的家目錄下建立file.txt檔案。可以在crontab檔案裡寫入:

12 17 * * * touch /home/oscar/file.txt複製程式碼

12表示分鐘,17表示小時,其他三個區域是*,最後的命令是 touch /home/oscar/file.txt。

路徑最好用絕對路徑,因為你並不能確定cron命令執行這些語句的時候是在哪個目錄。

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

然後,儲存退出Nano。如果語法正確的話,crontab會顯示:

crontab: installing new crontab複製程式碼

意思是:安裝新的crontab檔案。

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

現在,既然已經設定好了。那麼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檔案。

Linux 探索之旅 | 第三部分第五課:延時執行,唯慢不破

可以看到,我們執行crontab -l,此時我們有一個crontab檔案,顯示的內容就是我們之前用Nano編輯器填寫的。

然後我們用crontab -r來刪除crontab檔案,則再用crontab -l命令時,就顯示《no crontab for oscar》,就是又不存在crontab檔案了,也就沒有定時執行的任務了。

總結


  1. date命令可以顯示系統時間,可以按自定義格式顯示,也可以修改系統時間。

  2. at命令可以延時執行程式。但是它只能執行一次。

  3. 分號,&&和||都可以用來連線多個命令:用於依次執行前後命令。

  4. sleep命令用於使前後兩個命令執行之間間隔一定時間。

  5. crontab用於定時執行程式。例如:每天17點12分,每禮拜二和禮拜三在12點,每個月的7號,等等。我們用crontbab -e來修改crontab程式。

第三部分測驗題預告


今天的課就到這裡,一起加油吧!

下一課我們學習:第三部分測驗題


微信公眾號「程式設計師聯盟」ProgrammerLeague
我是謝恩銘,在巴黎奮鬥的軟體工程師。
我的簡介
我的經歷
熱愛生活,喜歡游泳,略懂烹飪。
人生格言:“向著標杆直跑”

相關文章