Linux就該這么學》最新正式版已出版上市,同學們可在線上京東網當當網淘寶網亞馬遜等電商平臺購買。

*亦可就近在新華書店購買*

章節簡述:

本章首先講解如何使用Vim編輯器來編寫、修改文檔,然后通過逐個配置主機名稱、系統網卡以及Yum軟件倉庫參數文件等實驗,幫助讀者加深Vim編輯器中諸多命令、快捷鍵、模式切換方法的理解。然后把前面章節中講解的Linux命令、命令語法與Shell腳本中的各種流程控制語句通過Vim編輯器寫到Shell腳本中結合到一起,實現最終能夠自動化工作的腳本文件。本章最后演示了怎樣通過at命令與crond計劃任務服務來分別實現一次性的系統任務設置和長期性的系統任務設置,從而讓日常的工作更加高效,更自動化。

4.1 Vim文本編輯器

每當在講課時遇到需要讓學生記住的知識點時,為了能讓他們打起精神來,我都會突然提高嗓門,因此有句話他們記得尤其深刻:“在Linux系統中一切都是文件,而配置一個服務就是在修改其配置文件的參數”。而且在日常工作中大家也肯定免不了要編寫文檔,這些工作都是通過文本編輯器來完成的。劉遄老師寫作本書的目的是讓讀者切實掌握Linux系統的運維方法,而不是僅僅停留在“會用某個操作系統”的層面上,所以我們這里選擇使用Vim文本編輯器,它默認會安裝在當前所有的Linux操作系統上,是一款超棒的文本編輯器。

Vim之所以能得到廣大廠商與用戶的認可,原因在于Vim編輯器中設置了三種模式—命令模式、末行模式和編輯模式,每種模式分別又支持多種不同的命令快捷鍵,這大大提高了工作效率,而且用戶在習慣之后也會覺得相當順手。要想高效率地操作文本,就必須先搞清這三種模式的操作區別以及模式之間的切換方法(見圖4-1)。

命令模式:控制光標移動,可對文本進行復制、粘貼、刪除和查找等工作。

輸入模式:正常的文本錄入。

末行模式:保存或退出文檔,以及設置編輯環境。

vim不同模式間的切換

圖4-1? Vim編輯器模式的切換方法

在每次運行Vim編輯器時,默認進入命令模式,此時需要先切換到輸入模式后再進行文檔編寫工作,而每次在編寫完文檔后需要先返回命令模式,然后再進入末行模式,執行文檔的保存或退出操作。在Vim中,無法直接從輸入模式切換到末行模式。Vim編輯器中內置的命令有成百上千種用法,為了能夠幫助讀者更快地掌握Vim編輯器,表4-1總結了在命令模式中最常用的一些命令。

表4-1????????????????????????????????????????????????????? Vim中常用的命令

命令 作用
dd 刪除(剪切)光標所在整行
5dd 刪除(剪切)從光標處開始的5行
yy 復制光標所在整行
5yy 復制從光標處開始的5行
n 顯示搜索命令定位到的下一個字符串
N 顯示搜索命令定位到的上一個字符串
u 撤銷上一步的操作
p 將之前刪除(dd)或復制(yy)過的數據粘貼到光標后面

末行模式主要用于保存或退出文件,以及設置Vim編輯器的工作環境,還可以讓用戶執行外部的Linux命令或跳轉到所編寫文檔的特定行數。要想切換到末行模式,在命令模式中輸入一個冒號就可以了。末行模式中可用的命令如表4-2所示。

表4-2????????????????????????????????????????????????? 末行模式中可用的命令

命令 作用
:w 保存
:q 退出
:q! 強制退出(放棄對文檔的修改內容)
:wq! 強制保存退出
:set nu 顯示行號
:set nonu 不顯示行號
:命令 執行該命令
:整數 跳轉到該行
:s/one/two 將當前光標所在行的第一個one替換成two
:s/one/two/g 將當前光標所在行的所有one替換成two
:%s/one/two/g 將全文中的所有one替換成two
?字符串 在文本中從下至上搜索該字符串
/字符串 在文本中從上至下搜索該字符串

4.1.1 編寫簡單文檔

目前為止,大家已經具備了在Linux系統中編寫文檔的理論基礎了,接下來我們一起動手編寫一個簡單的腳本文檔。劉遄老師會盡力把所有操作步驟和按鍵過程都標注出來,如果忘記了某些快捷鍵命令的作用,可以再返回前文進行復習。

編寫腳本文檔的第1步就是給文檔取個名字,這里將其命名為practice.txt。如果存在該文檔,則是打開它。如果不存在,則是創建一個臨時的輸入文件,如圖4-2所示。

第1步:創建文檔。

圖4-2? 嘗試編寫腳本文檔

打開practice.txt文檔后,默認進入的是Vim編輯器的命令模式。此時只能執行該模式下的命令,而不能隨意輸入文本內容,我們需要切換到輸入模式才可以編寫文檔。

在圖4-1中提到,可以分別使用a、i、o三個鍵從命令模式切換到輸入模式。其中,a鍵與i鍵分別是在光標后面一位和光標當前位置切換到輸入模式,而o鍵則是在光標的下面再創建一個空行,此時可敲擊a鍵進入到編輯器的輸入模式,如圖4-3所示。

第2步:敲擊字母“a”,進入輸入模式。

圖4-3? 切換至編輯器的輸入模式

進入輸入模式后,可以隨意輸入文本內容,Vim編輯器不會把您輸入的文本內容當作命令而執行,如圖4-4所示。

第3步:輸入一行字符。

圖4-4? 在編輯器中輸入文本內容

在編寫完之后,想要保存并退出,必須先敲擊鍵盤Esc鍵從輸入模式返回命令模式,如圖4-5所示。然后再輸入:wq!切換到末行模式才能完成保存退出操作,如圖4-6所示。

第4步:敲擊[ESC]返回到命令模式。

圖4-5? Vim編輯器的命令模式

第5步:敲擊“:wq”,保存并退出。

圖4-6? Vim編輯器的末行模式

當在末行模式中輸入:wq!命令時,就意味著強制保存并退出文檔。然后便可以用cat命令查看保存后的文檔內容了,如圖4-7所示。

第6步:查看文檔的內容。

圖4-7 查看文檔的內容

是不是很簡單?!繼續編輯這個文檔。因為要在原有文本內容的下面追加內容,所以在命令模式中敲擊o鍵進入輸入模式更會高效,操作如圖4-8、圖4-9與圖4-10所示。

第7步:編輯文件。

圖4-8? 再次通過Vim編輯器編寫文檔

第8步:敲擊字母“o”,進入到輸入模式。

圖4-9? 進入Vim編輯器的輸入模式

第9步:輸入一行字符。

圖4-10? 追加寫入一行文本內容

因為此時已經修改了文本內容,所以Vim編輯器在我們嘗試直接退出文檔而不保存的時候就會拒絕我們的操作了。此時只能強制退出才可以結束本次輸入操作,如圖4-11、圖4-12和圖4-13所示。

第10步:返回命令模式后嘗試“:q”退出不保存。

圖4-11? 嘗試退出文本編輯器

第11步:提示內容已被修改,不能退出。

圖4-12? 因文件已被修改而拒絕退出操作

現在大家也算是具有了一些Vim編輯器的實戰經驗了,應該也感覺沒有想象中那么難吧。現在查看文本的內容,果然發現追加輸入的內容并沒有被保存下來,如圖4-14所示。

大家在學完了理論知識之后又自己動手編寫了一個文本,現在是否感覺成就滿滿呢?接下來將會由淺入深為讀者安排三個小任務。為了徹底掌握Vim編輯器的使用,大家一定要逐個完成不許偷懶,如果在完成這三個任務期間忘記了相關命令,可返回前文進一步復習掌握。

第12步:敲擊“:q!”后強制退出不保存。

圖4-13 ?強制退出文本編輯器

第13步:查看文檔,發現第二句確實沒保存。

圖4-14 ?查看最終編寫成的文本內容

4.1.2 配置主機名稱

為了便于在局域網中查找某臺特定的主機,或者對主機進行區分,除了要有IP地址外,還要為主機配置一個主機名,主機之間可以通過這個類似于域名的名稱來相互訪問。在Linux系統中,主機名大多保存在/etc/hostname文件中,接下來將/etc/hostname文件的內容修改為“linuxprobe.com”,步驟如下。

第1步:使用Vim編輯器修改“/etc/hostname”主機名稱文件。

第2步:把原始主機名稱刪除后追加“linuxprobe.com”。注意,使用Vim編輯器修改主機名稱文件后,要在末行模式下執行:wq!命令才能保存并退出文檔。

第3步:保存并退出文檔,然后使用hostname命令檢查是否修改成功。

[[email protected] ~]# vim /etc/hostname
linuxprobe.com

hostname命令用于查看當前的主機名稱,但有時主機名稱的改變不會立即同步到系統中,所以如果發現修改完成后還顯示原來的主機名稱,可重啟虛擬機后再行查看:

[[email protected] ~]# hostname
linuxprobe.com
4.1.3 配置網卡信息

網卡IP地址配置的是否正確是兩臺服務器是否可以相互通信的前提。在Linux系統中,一切都是文件,因此配置網絡服務的工作其實就是在編輯網卡配置文件,因此這個小任務不僅可以幫助您練習使用Vim編輯器,而且也為您后面學習Linux中的各種服務配置打下了堅實的基礎。當您認真學習完本書后,一定會特別有成就感,因為本書前面的基礎部分非常扎實,而后面內容則具有幾乎一致的網卡IP地址和運行環境,從而確保您全身心地投入到各類服務程序的學習上,而不用操心系統環境的問題。

如果您具備一定的運維經驗或者熟悉早期的Linux系統,則在學習本書時會遇到一些不容易接受的差異變化。在RHEL 5、RHEL 6中,網卡配置文件的前綴為eth,第1塊網卡為eth0,第2塊網卡為eth1;以此類推。而在RHEL 7中,網卡配置文件的前綴則以ifcfg開始,加上網卡名稱共同組成了網卡配置文件的名字,例如ifcfg-eno16777736;好在除了文件名變化外也沒有其他大的區別。

現在有一個名稱為ifcfg-eno16777736的網卡設備,我們將其配置為開機自啟動,并且IP地址、子網、網關等信息由人工指定,其步驟應該如下所示。

第1步:首先切換到/etc/sysconfig/network-scripts目錄中(存放著網卡的配置文件)。

第2步:使用Vim編輯器修改網卡文件ifcfg-eno16777736,逐項寫入下面的配置參數并保存退出。由于每臺設備的硬件及架構是不一樣的,因此請讀者使用ifconfig命令自行確認各自網卡的默認名稱。

設備類型:TYPE=Ethernet

地址分配模式:BOOTPROTO=static

網卡名稱:NAME=eno16777736

是否啟動:ONBOOT=yes

IP地址:IPADDR=192.168.10.10

子網掩碼:NETMASK=255.255.255.0

網關地址:GATEWAY=192.168.10.1

DNS地址:DNS1=192.168.10.1

第3步:重啟網絡服務并測試網絡是否聯通。

進入到網卡配置文件所在的目錄,然后編輯網卡配置文件,在其中填入下面的信息:

[[email protected] ~]# cd /etc/sysconfig/network-scripts/
[[email protected] network-scripts]# vim ifcfg-eno16777736
TYPE=Ethernet
BOOTPROTO=static
NAME=eno16777736
ONBOOT=yes
IPADDR=192.168.10.10
NETMASK=255.255.255.0
GATEWAY=192.168.10.1
DNS1=192.168.10.1

執行重啟網卡設備的命令(在正常情況下不會有提示信息),然后通過ping命令測試網絡能否聯通。由于在Linux系統中ping命令不會自動終止,因此需要手動按下Ctrl-c鍵來強行結束進程。

[[email protected] network-scripts]# systemctl restart network
[[email protected] network-scripts]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.097 ms
^C
--- 192.168.10.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.059/0.080/0.097/0.013 ms
4.1.4 配置Yum倉庫

本書前面講到,Yum軟件倉庫的作用是為了進一步簡化RPM管理軟件的難度以及自動分析所需軟件包及其依賴關系的技術。可以把Yum想象成是一個碩大的軟件倉庫,里面保存有幾乎所有常用的工具,而且只需要說出所需的軟件包名稱,系統就會自動為您搞定一切。

既然要使用Yum軟件倉庫,就要先把它搭建起來,然后將其配置規則確定好才行。鑒于第6章才會講解Linux的存儲結構和設備掛載操作,所以我們當前還是將重心放到Vim編輯器的學習上。如果遇到看不懂的參數也不要緊,后面章節會單獨講解。搭建并配置Yum軟件倉庫的大致步驟如下所示。

第1步:進入到/etc/yum.repos.d/目錄中(因為該目錄存放著Yum軟件倉庫的配置文件)。

第2步:使用Vim編輯器創建一個名為rhel7.repo的新配置文件(文件名稱可隨意,但后綴必須為.repo),逐項寫入下面加粗的配置參數并保存退出(不要寫后面的中文注釋)。

[rhel-media] :Yum軟件倉庫唯一標識符,避免與其他倉庫沖突。

name=linuxprobe:Yum軟件倉庫的名稱描述,易于識別倉庫用處。

baseurl=file:///media/cdrom:提供的方式包括FTP(ftp://..)、HTTP(http://..)、本地(file:///..)。

enabled=1:設置此源是否可用;1為可用,0為禁用。

gpgcheck=1:設置此源是否校驗文件;1為校驗,0為不校驗。

gpgkey=file:///media/cdrom/RPM-GPG-KEY-redhat-release:若上面參數開啟校驗,那么請指定公鑰文件地址。

第3步:按配置參數的路徑掛載光盤,并把光盤掛載信息寫入到/etc/fstab文件中。

第4步:使用“yum install httpd -y”命令檢查Yum軟件倉庫是否已經可用。

進入/etc/yum.repos.d目錄中后創建Yum配置文件:

[[email protected] ~]# cd /etc/yum.repos.d/
[[email protected] yum.repos.d]# vim rhel7.repo
[rhel7]
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0

創建掛載點后進行掛載操作,并設置成開機自動掛載(詳見第6章)。嘗試使用Yum軟件倉庫來安裝Web服務,出現Complete!則代表配置正確:

[[email protected]?yum.repos.d]#?mkdir?-p?/media/cdrom
[[email protected]?yum.repos.d]#?mount?/dev/cdrom?/media/cdrom
mount:?/dev/sr0?is?write-protected,?mounting?read-only
[[email protected]?yum.repos.d]#?vim?/etc/fstab
/dev/cdrom?/media/cdrom?iso9660?defaults?0?0
[[email protected] ~]# yum install httpd
Loaded plugins: langpacks, product-id, subscription-manager
………………省略部分輸出信息………………
Dependencies Resolved
================================================================================
 Package Arch Version Repository Size
================================================================================
Installing:
 httpd x86_64 2.4.6-17.el7 rhel 1.2 M
Installing for dependencies:
 apr x86_64 1.4.8-3.el7 rhel 103 k
 apr-util x86_64 1.5.2-6.el7 rhel 92 k
 httpd-tools x86_64 2.4.6-17.el7 rhel 77 k
 mailcap noarch 2.1.41-2.el7 rhel 31 k
Transaction Summary
================================================================================
Install 1 Package (+4 Dependent packages)
Total download size: 1.5 M
Installed size: 4.3 M
Is this ok [y/d/N]: y
Downloading packages:
--------------------------------------------------------------------------------
………………省略部分輸出信息………………
Complete!

出現問題?大膽提問!

因讀者們硬件不同或操作錯誤都可能導致實驗配置出錯,請耐心再仔細看看操作步驟吧,不要氣餒~

Linux技術交流請加A群:560843(滿),B群:340829(推薦),C群:463590(推薦),點此查看全國群

*本群特色:通過口令驗證確保每一個群員都是《Linux就該這么學》的讀者,答疑更有針對性,不定期免費領取定制禮品。

4.2 編寫Shell腳本

可以將Shell終端解釋器當作人與計算機硬件之間的“翻譯官”,它作為用戶與Linux系統內部的通信媒介,除了能夠支持各種變量與參數外,還提供了諸如循環、分支等高級編程語言才有的控制結構特性。要想正確使用Shell中的這些功能特性,準確下達命令尤為重要。Shell腳本命令的工作方式有兩種:交互式和批處理。

交互式(Interactive):用戶每輸入一條命令就立即執行。

批處理(Batch):由用戶事先編寫好一個完整的Shell腳本,Shell會一次性執行腳本中諸多的命令。

在Shell腳本中不僅會用到前面學習過的很多Linux命令以及正則表達式、管道符、數據流重定向等語法規則,還需要把內部功能模塊化后通過邏輯語句進行處理,最終形成日常所見的Shell腳本。

查看SHELL變量可以發現當前系統已經默認使用Bash作為命令行終端解釋器了:

[[email protected] ~]# echo $SHELL
/bin/bash
4.2.1 編寫簡單的腳本

估計讀者在看完上文中有關Shell腳本的復雜描述后,會累覺不愛吧。但是,上文指的是一個高級Shell腳本的編寫原則,其實使用Vim編輯器把Linux命令按照順序依次寫入到一個文件中,這就是一個簡單的腳本了。

例如,如果想查看當前所在工作路徑并列出當前目錄下所有的文件及屬性信息,實現這個功能的腳本應該類似于下面這樣:

[[email protected] ~]# vim example.sh
#!/bin/bash 
#For Example BY linuxprobe.com 
pwd 
ls -al

Shell腳本文件的名稱可以任意,但為了避免被誤以為是普通文件,建議將.sh后綴加上,以表示是一個腳本文件。在上面的這個example.sh腳本中實際上出現了三種不同的元素:第一行的腳本聲明(#!)用來告訴系統使用哪種Shell解釋器來執行該腳本;第二行的注釋信息(#)是對腳本功能和某些命令的介紹信息,使得自己或他人在日后看到這個腳本內容時,可以快速知道該腳本的作用或一些警告信息;第三、四行的可執行語句也就是我們平時執行的Linux命令了。什么?!你們不相信這么簡單就編寫出來了一個腳本程序,那我們來執行一下看看結果:

[[email protected] ~]# bash example.sh
/root/Desktop
total 8
drwxr-xr-x. 2 root root 23 Jul 23 17:31 .
dr-xr-x---. 14 root root 4096 Jul 23 17:31 ..
-rwxr--r--. 1 root root 55 Jul 23 17:31 example.sh

除了上面用bash解釋器命令直接運行Shell腳本文件外,第二種運行腳本程序的方法是通過輸入完整路徑的方式來執行。但默認會因為權限不足而提示報錯信息,此時只需要為腳本文件增加執行權限即可(詳見第5章)。初次學習Linux系統的讀者不用心急,等下一章學完用戶身份和權限后再來做這個實驗也不遲:

[[email protected] ~]# ./example.sh
bash: ./Example.sh: Permission denied
[[email protected] ~]# chmod u+x example.sh
[[email protected] ~]# ./example.sh
/root/Desktop
total 8
drwxr-xr-x. 2 root root 23 Jul 23 17:31 .
dr-xr-x---. 14 root root 4096 Jul 23 17:31 ..
-rwxr--r--. 1 root root 55 Jul 23 17:31 example.sh
4.2.2 接收用戶的參數

但是,像上面這樣的腳本程序只能執行一些預先定義好的功能,未免太過死板了。為了讓Shell腳本程序更好地滿足用戶的一些實時需求,以便靈活完成工作,必須要讓腳本程序能夠像之前執行命令時那樣,接收用戶輸入的參數。

其實,Linux系統中的Shell腳本語言早就考慮到了這些,已經內設了用于接收參數的變量,變量之間可以使用空格間隔。例如$0對應的是當前Shell腳本程序的名稱,$#對應的是總共有幾個參數,$*對應的是所有位置的參數值,$?對應的是顯示上一次命令的執行返回值,而$1、$2、$3……則分別對應著第N個位置的參數值,如圖4-15所示。

圖4-15? Shell腳本程序中的參數位置變量

理論過后我們來練習一下。嘗試編寫一個腳本程序示例,通過引用上面的變量參數來看下真實效果:

[[email protected] ~]# vim example.sh
#!/bin/bash
echo "當前腳本名稱為$0"
echo "總共有$#個參數,分別是$*。"
echo "第1個參數為$1,第5個為$5。"
[[email protected] ~]# sh example.sh one two three four five six
當前腳本名稱為example.sh
總共有6個參數,分別是one two three four five six。
第1個參數為one,第5個為five。
4.2.3 判斷用戶的參數

學習是一個登堂入室、由淺入深的過程。在學習完Linux命令、掌握Shell腳本語法變量和接收用戶輸入的信息之后,就要踏上新的高度—能夠進一步處理接收到的用戶參數。

在本書前面章節中講到,系統在執行mkdir命令時會判斷用戶輸入的信息,即判斷用戶指定的文件夾名稱是否已經存在,如果存在則提示報錯;反之則自動創建。Shell腳本中的條件測試語法可以判斷表達式是否成立,若條件成立則返回數字0,否則便返回其他隨機數值。條件測試語法的執行格式如圖4-16所示。切記,條件表達式兩邊均應有一個空格。

測試語句格式

圖4-16? 條件測試語句的執行格式


按照測試對象來劃分,條件測試語句可以分為4種:

文件測試語句;

邏輯測試語句;

整數值比較語句;

字符串比較語句。

文件測試即使用指定條件來判斷文件是否存在或權限是否滿足等情況的運算符,具體的參數如表4-3所示。

表4-3??????????????????????????????????????????????????? 文件測試所用的參數

操作符 作用
-d 測試文件是否為目錄類型
-e 測試文件是否存在
-f 判斷是否為一般文件
-r 測試當前用戶是否有權限讀取
-w 測試當前用戶是否有權限寫入
-x 測試當前用戶是否有權限執行

下面使用文件測試語句來判斷/etc/fstab是否為一個目錄類型的文件,然后通過Shell解釋器的內設$?變量顯示上一條命令執行后的返回值。如果返回值為0,則目錄存在;如果返回值為非零的值,則意味著目錄不存在:

[[email protected] ~]# [ -d /etc/fstab ]
[[email protected] ~]# echo $?
1

再使用文件測試語句來判斷/etc/fstab是否為一般文件,如果返回值為0,則代表文件存在,且為一般文件:

[[email protected] ~]# [ -f /etc/fstab ]
[[email protected] ~]# echo $?
0

邏輯語句用于對測試結果進行邏輯分析,根據測試結果可實現不同的效果。例如在Shell終端中邏輯“與”的運算符號是&&,它表示當前面的命令執行成功后才會執行它后面的命令,因此可以用來判斷/dev/cdrom文件是否存在,若存在則輸出Exist字樣。

[[email protected] ~]# [ -e /dev/cdrom ] && echo "Exist"
Exist

除了邏輯“與”外,還有邏輯“或”,它在Linux系統中的運算符號為||,表示當前面的命令執行失敗后才會執行它后面的命令,因此可以用來結合系統環境變量USER來判斷當前登錄的用戶是否為非管理員身份:

[[email protected] ~]# echo $USER
root
[[email protected] ~]# [ $USER = root ] || echo "user"
[[email protected] ~]# su - linuxprobe 
[[email protected] ~]$ [ $USER = root ] || echo "user"
user

第三種邏輯語句是“非”,在Linux系統中的運算符號是一個嘆號(!),它表示把條件測試中的判斷結果取相反值。也就是說,如果原本測試的結果是正確的,則將其變成錯誤的;原本測試錯誤的結果則將其變成正確的。

我們現在切換回到root管理員身份,再判斷當前用戶是否為一個非管理員的用戶。由于判斷結果因為兩次否定而變成正確,因此會正常地輸出預設信息:

[[email protected] ~]$ exit
logout
[[email protected] root]# [ $USER != root ] || echo "administrator"
administrator

就技術圖書的寫作來講,一般有兩種套路:讓讀者真正搞懂技術了;讓讀者覺得自己搞懂技術了。因此市面上很多淺顯的圖書會讓讀者在學完之后感覺進步特別快,這基本上是作者有意為之,目的就是讓您覺得“圖書很有料,自己收獲很大”,但是在步入工作崗位后就露出短板吃大虧。所以劉遄老師決定繼續提高難度,為讀者增加一個綜合的示例,一方面作為前述知識的總結,另一方面幫助讀者夯實基礎,能夠在今后工作中更靈活地使用邏輯符號。

當前我們正在登錄的即為管理員用戶—root。下面這個示例的執行順序是,先判斷當前登錄用戶的USER變量名稱是否等于root,然后用邏輯運算符“非”進行取反操作,效果就變成了判斷當前登錄的用戶是否為非管理員用戶了。最后若條件成立則會根據邏輯“與”運算符輸出user字樣;或條件不滿足則會通過邏輯“或”運算符輸出root字樣,而如果前面的&&不成立才會執行后面的||符號。

[[email protected] ~]# [ $USER != root ] && echo "user" || echo "root"
root

整數比較運算符僅是對數字的操作,不能將數字與字符串、文件等內容一起操作,而且不能想當然地使用日常生活中的等號、大于號、小于號等來判斷。因為等號與賦值命令符沖突,大于號和小于號分別與輸出重定向命令符和輸入重定向命令符沖突。因此一定要使用規范的整數比較運算符來進行操作。可用的整數比較運算符如表4-4所示。

表4-4????????????????????????????????????????????????? 可用的整數比較運算符

操作符 作用
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

接下來小試牛刀。我們先測試一下10是否大于10以及10是否等于10(通過輸出的返回值內容來判斷):

[[email protected] ~]# [ 10 -gt 10 ]
[[email protected] ~]# echo $?
1
[[email protected] ~]# [ 10 -eq 10 ]
[[email protected] ~]# echo $?
0

在2.4節曾經講過free命令,它可以用來獲取當前系統正在使用及可用的內存量信息。接下來先使用free -m命令查看內存使用量情況(單位為MB),然后通過grep Mem:命令過濾出剩余內存量的行,再用awk '{print $4}'命令只保留第四列,最后用FreeMem=`語句`的方式把語句內執行的結果賦值給變量。

這個演示確實有些難度,但看懂后會覺得很有意思,沒準在運維工作中也會用得上。

[[email protected] ~]# free -m
            total     used     free     shared     buffers     cached
Mem:        1826      1244     582      9          1           413
-/+ buffers/cache:    830 996
Swap:       2047      0        2047
[[email protected]?~]# free -m | grep Mem:
Mem:        1826      1244     582      9 
[[email protected]?~]# free -m | grep Mem: | awk '{print $4}'
582
[[email protected] ~]# FreeMem=`free -m | grep Mem: | awk '{print $4}'`
[[email protected] ~]# echo $FreeMem 
582

上面用于獲取內存可用量的命令以及步驟可能有些“超綱”了,如果不能理解領會也不用擔心,接下來才是重點。我們使用整數運算符來判斷內存可用量的值是否小于1024,若小于則會提示“Insufficient Memory”(內存不足)的字樣:

[[email protected] ~]# [ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
Insufficient Memory

字符串比較語句用于判斷測試字符串是否為空值,或兩個字符串是否相同。它經常用來判斷某個變量是否未被定義(即內容為空值),理解起來也比較簡單。字符串比較中常見的運算符如表4-5所示。

表4-5??????????????????????????????????????????????? 常見的字符串比較運算符

操作符 作用
= 比較字符串內容是否相同
!= 比較字符串內容是否不同
-z 判斷字符串內容是否為空

接下來通過判斷String變量是否為空值,進而判斷是否定義了這個變量:

[[email protected] ~]# [ -z $String ]
[[email protected] ~]# echo $?
0

再嘗試引入邏輯運算符來試一下。當用于保存當前語系的環境變量值LANG不是英語(en.US)時,則會滿足邏輯測試條件并輸出“Not en.US”(非英語)的字樣:

[[email protected] ~]# echo $LANG
en_US.UTF-8
[[email protected] ~]# [ $LANG != "en.US" ] && echo "Not en.US"
Not en.US

出現問題?大膽提問!

因讀者們硬件不同或操作錯誤都可能導致實驗配置出錯,請耐心再仔細看看操作步驟吧,不要氣餒~

Linux技術交流請加A群:560843(滿),B群:340829(推薦),C群:463590(推薦),點此查看全國群

*本群特色:通過口令驗證確保每一個群員都是《Linux就該這么學》的讀者,答疑更有針對性,不定期免費領取定制禮品。

4.3 流程控制語句

盡管此時可以通過使用Linux命令、管道符、重定向以及條件測試語句來編寫最基本的Shell腳本,但是這種腳本并不適用于生產環境。原因是它不能根據真實的工作需求來調整具體的執行命令,也不能根據某些條件實現自動循環執行。例如,我們需要批量創建1000位用戶,首先要判斷這些用戶是否已經存在;若不存在,則通過循環語句讓腳本自動且依次創建他們。

接下來我們通過if、for、while、case這4種流程控制語句來學習編寫難度更大、功能更強的Shell腳本。為了保證下文的實用性和趣味性,做到寓教于樂,我會盡可能多地講解各種不同功能的Shell腳本示例,而不是逮住一個腳本不放,在它原有內容的基礎上修修補補。盡管這種修補式的示例教學也可以讓讀者明白理論知識,但是卻無法開放思路,不利于日后的工作。

4.3.1 if條件測試語句

if條件測試語句可以讓腳本根據實際情況自動執行相應的命令。從技術角度來講,if語句分為單分支結構、雙分支結構、多分支結構;其復雜度隨著靈活度一起逐級上升。

if條件語句的單分支結構由if、then、fi關鍵詞組成,而且只在條件成立后才執行預設的命令,相當于口語的“如果……那么……”。單分支的if語句屬于最簡單的一種條件判斷結構,語法格式如圖4-17所示。
%e5%8d%95%e5%88%86%e6%94%af%e7%bb%93%e6%9e%84

圖4-17? 單分支的if語句

下面使用單分支的if條件語句來判斷/media/cdrom文件是否存在,若存在就結束條件判斷和整個Shell腳本,反之則去創建這個目錄:

[[email protected] ~]# vim mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi

由于第5章才講解用戶身份與權限,因此這里繼續用“bash 腳本名稱”的方式來執行腳本。在正常情況下,順利執行完腳本文件后沒有任何輸出信息,但是可以使用ls命令驗證/media/cdrom目錄是否已經成功創建:

[[email protected] ~]# bash mkcdrom.sh
[[email protected] ~]# ls -d /media/cdrom
/media/cdrom

if條件語句的雙分支結構由if、then、else、fi關鍵詞組成,它進行一次條件匹配判斷,如果與條件匹配,則去執行相應的預設命令;反之則去執行不匹配時的預設命令,相當于口語的“如果……那么……或者……那么……”。if條件語句的雙分支結構也是一種很簡單的判斷結構,語法格式如圖4-18所示。

%e5%8f%8c%e5%88%86%e6%94%af%e7%bb%93%e6%9e%84

圖4-18?雙分支的if條件語句

下面使用雙分支的if條件語句來驗證某臺主機是否在線,然后根據返回值的結果,要么顯示主機在線信息,要么顯示主機不在線信息。這里的腳本主要使用ping命令來測試與對方主機的網絡聯通性,而Linux系統中的ping命令不像Windows一樣嘗試4次就結束,因此為了避免用戶等待時間過長,需要通過-c參數來規定嘗試的次數,并使用-i參數定義每個數據包的發送間隔,以及使用-W參數定義等待超時時間。

[[email protected] ~]# vim chkhost.sh
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is On-line."
else
echo "Host $1 is Off-line."
fi

我們在4.2.3小節中用過$?變量,作用是顯示上一次命令的執行返回值。若前面的那條語句成功執行,則$?變量會顯示數字0,反之則顯示一個非零的數字(可能為1,也可能為2,取決于系統版本)。因此可以使用整數比較運算符來判斷$?變量是否為0,從而獲知那條語句的最終判斷情況。這里的服務器IP地址為192.168.10.10,我們來驗證一下腳本的效果:

[[email protected] ~]# bash chkhost.sh 192.168.10.10
Host 192.168.10.10 is On-line.
[[email protected] ~]# bash chkhost.sh 192.168.10.20
Host 192.168.10.20 is Off-line.

if條件語句的多分支結構由if、then、else、elif、fi關鍵詞組成,它進行多次條件匹配判斷,這多次判斷中的任何一項在匹配成功后都會執行相應的預設命令,相當于口語的“如果……那么……如果……那么……”。if條件語句的多分支結構是工作中最常使用的一種條件判斷結構,盡管相對復雜但是更加靈活,語法格式如圖4-19所示。 %e5%a4%9a%e5%88%86%e6%94%af%e7%bb%93%e6%9e%84

圖 4-19 多分支的if條件語句

下面使用多分支的if條件語句來判斷用戶輸入的分數在哪個成績區間內,然后輸出如Excellent、Pass、Fail等提示信息。在Linux系統中,read是用來讀取用戶輸入信息的命令,能夠把接收到的用戶輸入信息賦值給后面的指定變量,-p參數用于向用戶顯示一定的提示信息。在下面的腳本示例中,只有當用戶輸入的分數大于等于85分且小于等于100分,才輸出Excellent字樣;若分數不滿足該條件(即匹配不成功),則繼續判斷分數是否大于等于70分且小于等于84分,如果是,則輸出Pass字樣;若兩次都落空(即兩次的匹配操作都失敗了),則輸出Fail字樣:

[[email protected] ~]# vim chkscore.sh
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail" 
fi
[[email protected] ~]# bash chkscore.sh
Enter your score(0-100):88
88 is Excellent
[[email protected] ~]# bash chkscore.sh 
Enter your score(0-100):80
80 is Pass

下面執行該腳本。當用戶輸入的分數分別為30和200時,其結果如下:

[[email protected] ~]# bash chkscore.sh? 
Enter your score(0-100):30
30 is Fail
[[email protected] ~]# bash chkscore.sh
Enter your score(0-100):200 
200 is Fail

為什么輸入的分數為200時,依然顯示Fail呢?原因很簡單—沒有成功匹配腳本中的兩個條件判斷語句,因此自動執行了最終的兜底策略。可見,這個腳本還不是很完美,建議讀者自行完善這個腳本,使得用戶在輸入大于100或小于0的分數時,給予Error報錯字樣的提示。

4.3.2 for條件循環語句

for循環語句允許腳本一次性讀取多個信息,然后逐一對信息進行操作處理,當要處理的數據有范圍時,使用for循環語句再適合不過了。for循環語句的語法格式如圖4-20所示。

for%e6%9d%a1%e4%bb%b6%e8%af%ad%e5%8f%a5

圖4-20? for循環語句的語法格式

下面使用for循環語句從列表文件中讀取多個用戶名,然后為其逐一創建用戶賬戶并設置密碼。首先創建用戶名稱的列表文件users.txt,每個用戶名稱單獨一行。讀者可以自行決定具體的用戶名稱和個數:

[[email protected] ~]# vim users.txt
andy
barry
carl
duke
eric
george

接下來編寫Shell腳本Example.sh。在腳本中使用read命令讀取用戶輸入的密碼值,然后賦值給PASSWD變量,并通過-p參數向用戶顯示一段提示信息,告訴用戶正在輸入的內容即將作為賬戶密碼。在執行該腳本后,會自動使用從列表文件users.txt中獲取到所有的用戶名稱,然后逐一使用“id 用戶名”命令查看用戶的信息,并使用$?判斷這條命令是否執行成功,也就是判斷該用戶是否已經存在。

需要多說一句,/dev/null是一個被稱作Linux黑洞的文件,把輸出信息重定向到這個文件等同于刪除數據(類似于沒有回收功能的垃圾箱),可以讓用戶的屏幕窗口保持簡潔。

[[email protected] ~]# vim Example.sh
#!/bin/bash
read -p "Enter The Users Password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists"
else
useradd $UNAME &> /dev/null
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , Create success"
else
echo "$UNAME ,?Create failure"
fi
fi
done

執行批量創建用戶的Shell腳本Example.sh,在輸入為賬戶設定的密碼后將由腳本自動檢查并創建這些賬戶。由于已經將多余的信息通過輸出重定向符轉移到了/dev/null黑洞文件中,因此在正常情況下屏幕窗口除了“用戶賬戶創建成功”(Create success)的提示后不會有其他內容。

在Linux系統中,/etc/passwd是用來保存用戶賬戶信息的文件。如果想確認這個腳本是否成功創建了用戶賬戶,可以打開這個文件,看其中是否有這些新創建的用戶信息。

[[email protected] ~]# bash Example.sh
Enter The Users Password : linuxprobe
andy , Create success
barry , Create success
carl , Create success
duke , Create success
eric , Create success
george , Create success
[[email protected] ~]# tail -6 /etc/passwd
andy:x:1001:1001::/home/andy:/bin/bash
barry:x:1002:1002::/home/barry:/bin/bash
carl:x:1003:1003::/home/carl:/bin/bash
duke:x:1004:1004::/home/duke:/bin/bash
eric:x:1005:1005::/home/eric:/bin/bash
george:x:1006:1006::/home/george:/bin/bash

您還記得在學習雙分支if條件語句時,用到的那個測試主機是否在線的腳本么?既然我們現在已經掌握了for循環語句,不妨做些更酷的事情,比如嘗試讓腳本從文本中自動讀取主機列表,然后自動逐個測試這些主機是否在線。

首先創建一個主機列表文件ipadds.txt:

[[email protected] ~]# vim?ipadds.txt
192.168.10.10
192.168.10.11
192.168.10.12

然后前面的雙分支if條件語句與for循環語句相結合,讓腳本從主機列表文件ipadds.txt中自動讀取IP地址(用來表示主機)并將其賦值給HLIST變量,從而通過判斷ping命令執行后的返回值來逐個測試主機是否在線。腳本中出現的$(命令)是一種完全類似于第3章的轉義字符中反引號`命令`的Shell操作符,效果同樣是執行括號或雙引號括起來的字符串中的命令。大家在編寫腳本時,多學習幾種類似的新方法,可在工作中大顯身手:

[[email protected]?~]# vim CheckHosts.sh
#!/bin/bash
HLIST=$(cat ~/ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host $IP is On-line."
else
echo "Host $IP is Off-line."
fi
done
[[email protected] ~]# ./CheckHosts.sh
Host 192.168.10.10 is On-line.
Host 192.168.10.11 is Off-line.
Host 192.168.10.12 is Off-line.
4.3.3 while條件循環語句

while條件循環語句是一種讓腳本根據某些條件來重復執行命令的語句,它的循環結構往往在執行前并不確定最終執行的次數,完全不同于for循環語句中有目標、有范圍的使用場景。while循環語句通過判斷條件測試的真假來決定是否繼續執行命令,若條件為真就繼續執行,為假就結束循環。while語句的語法格式如圖4-21所示。 while%e6%9d%a1%e4%bb%b6%e8%af%ad%e5%8f%a5

圖4-21? while循環語句的語法格式

接下來結合使用多分支的if條件測試語句與while條件循環語句,編寫一個用來猜測數值大小的腳本Guess.sh。該腳本使用$RANDOM變量來調取出一個隨機的數值(范圍為0~32767),將這個隨機數對1000進行取余操作,并使用expr命令取得其結果,再用這個數值與用戶通過read命令輸入的數值進行比較判斷。這個判斷語句分為三種情況,分別是判斷用戶輸入的數值是等于、大于還是小于使用expr命令取得的數值。當前,現在這些內容不是重點,我們當前要關注的是while條件循環語句中的條件測試始終為true,因此判斷語句會無限執行下去,直到用戶輸入的數值等于expr命令取得的數值后,這兩者相等之后才運行exit 0命令,終止腳本的執行。

[[email protected] ~]# vim Guess.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品實際價格為0-999之間,猜猜看是多少?"
while true
do
read -p "請輸入您猜測的價格數目:" INT
let TIMES++
if [ $INT -eq $PRICE ] ; then
echo "恭喜您答對了,實際價格是 $PRICE"
echo "您總共猜測了 $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "太高了!"
else
echo "太低了!"
fi
done

在這個Guess.sh腳本中,我們添加了一些交互式的信息,從而使得用戶與系統的互動性得以增強。而且每當循環到let TIMES++命令時都會讓TIMES變量內的數值加1,用來統計循環總計執行了多少次。這可以讓用戶得知總共猜測了多少次之后,才猜對價格。

[[email protected] ~]# bash Guess.sh
商品實際價格為0-999之間,猜猜看是多少?
請輸入您猜測的價格數目:500
太低了!
請輸入您猜測的價格數目:800
太高了!
請輸入您猜測的價格數目:650
太低了!
請輸入您猜測的價格數目:720
太高了!
請輸入您猜測的價格數目:690
太低了!
請輸入您猜測的價格數目:700
太高了!
請輸入您猜測的價格數目:695
太高了!
請輸入您猜測的價格數目:692
太高了!
請輸入您猜測的價格數目:691
恭喜您答對了,實際價格是 691
您總共猜測了 9 次
4.3.4 case條件測試語句

如果您之前學習過C語言,看到這一小節的標題肯定會會心一笑“這不就是switch語句嘛!”是的,case條件測試語句和switch語句的功能非常相似!case語句是在多個范圍內匹配數據,若匹配成功則執行相關命令并結束整個條件測試;而如果數據不在所列出的范圍內,則會去執行星號(*)中所定義的默認命令。case語句的語法結構如圖4-22所示。

case%e6%9d%a1%e4%bb%b6%e8%af%ad%e5%8f%a5

圖4-22? case條件測試語句的語法結構

在前文介紹的Guess.sh腳本中有一個致命的弱點—只能接受數字!您可以嘗試輸入一個字母,會發現腳本立即就崩潰了。原因是字母無法與數字進行大小比較,例如,“a是否大于等于3”這樣的命題是完全錯誤的。我們必須有一定的措施來判斷用戶的輸入內容,當用戶輸入的內容不是數字時,腳本能予以提示,從而免于崩潰。

通過在腳本中組合使用case條件測試語句和通配符(詳見第3章),完全可以滿足這里的需求。接下來我們編寫腳本Checkkeys.sh,提示用戶輸入一個字符并將其賦值給變量KEY,然后根據變量KEY的值向用戶顯示其值是字母、數字還是其他字符。

[[email protected] ~]# vim Checkkeys.sh
#!/bin/bash
read -p "請輸入一個字符,并按Enter鍵確認:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您輸入的是 字母。"
;;
[0-9])
echo "您輸入的是 數字。"
;;
*)
echo "您輸入的是 空格、功能鍵或其他控制字符。"
esac
[[email protected] ~]# bash Checkkeys.sh
請輸入一個字符,并按Enter鍵確認:6
您輸入的是 數字。
[[email protected] ~]# bash Checkkeys.sh
請輸入一個字符,并按Enter鍵確認:p
您輸入的是 字母。
[[email protected] ~]# bash Checkkeys.sh
請輸入一個字符,并按Enter鍵確認:^[[15~
您輸入的是 空格、功能鍵或其他控制字符。
4.4?計劃任務服務程序

經驗豐富的系統運維工程師可以使得Linux在無需人為介入的情況下,在指定的時間段自動啟用或停止某些服務或命令,從而實現運維的自動化。盡管我們現在已經有了功能彪悍的腳本程序來執行一些批處理工作,但是,如果仍然需要在每天凌晨兩點敲擊鍵盤回車鍵來執行這個腳本程序,這簡直太痛苦了(當然,也可以訓練您的小貓在半夜按下回車鍵)。接下來,劉遄老師將向大家講解如何設置服務器的計劃任務服務,把周期性、規律性的工作交給系統自動完成。

計劃任務分為一次性計劃任務與長期性計劃任務,大家可以按照如下方式理解。

一次性計劃任務:今晚11點30分開啟網站服務。

長期性計劃任務:每周一的凌晨3點25分把/home/wwwroot目錄打包備份為backup.tar.gz。

顧名思義,一次性計劃任務只執行一次,一般用于滿足臨時的工作需求。我們可以用at命令實現這種功能,只需要寫成“at 時間”的形式就可以。如果想要查看已設置好但還未執行的一次性計劃任務,可以使用“at -l”命令;要想將其刪除,可以用“atrm 任務序號”。在使用at命令來設置一次性計劃任務時,默認采用的是交互式方法。例如,使用下述命令將系統設置為在今晚23:30分自動重啟網站服務。

[[email protected] ~]# at 23:30
at > systemctl restart httpd
at > 此處請同時按下Ctrl+d來結束編寫計劃任務
job 3 at Mon Apr 27 23:30:00 2015
[[email protected] ~]# at -l
3 Mon Apr 27 23:30:00 2016 a root

如果讀者想挑戰一下難度更大但簡捷性更高的方式,可以把前面學習的管道符(任意門)放到兩條命令之間,讓at命令接收前面echo命令的輸出信息,以達到通過非交互式的方式創建計劃一次性任務的目的。

[[email protected] ~]# echo "systemctl restart httpd" | at 23:30
job 4 at Mon Apr 27 23:30:00 2015
[[email protected] ~]# at -l
3 Mon Apr 27 23:30:00 2016 a root
4 Mon Apr 27 23:30:00 2016 a root

如果我們不小心設置了兩個一次性計劃任務,可以使用下面的命令輕松刪除其中一個:

[[email protected] ~]# atrm 3
[[email protected] ~]# at -l
4 Mon Apr 27 23:30:00 2016 a root

如果我們希望Linux系統能夠周期性地、有規律地執行某些具體的任務,那么Linux系統中默認啟用的crond服務簡直再適合不過了。創建、編輯計劃任務的命令為“crontab -e”,查看當前計劃任務的命令為“crontab -l”,刪除某條計劃任務的命令為“crontab -r”。另外,如果您是以管理員的身份登錄的系統,還可以在crontab命令中加上-u參數來編輯他人的計劃任務。

在正式部署計劃任務前,請先跟劉遄老師念一下口訣“分、時、日、月、星期 命令”。這是使用crond服務設置任務的參數格式(其格式見表4-6)。需要注意的是,如果有些字段沒有設置,則需要使用星號(*)占位,如圖4-23所示。 cron計劃任務的參數

圖4-23? 使用crond設置任務的參數格式

表4-6?????????????????????????????????????? 使用crond設置任務的參數字段說明

字段 說明
分鐘 取值為0~59的整數
小時 取值為0~23的任意整數
日期 取值為1~31的任意整數
月份 取值為1~12的任意整數
星期 取值為0~7的任意整數,其中0與7均為星期日
命令 要執行的命令或程序腳本

假設在每周一、三、五的凌晨3點25分,都需要使用tar命令把某個網站的數據目錄進行打包處理,使其作為一個備份文件。我們可以使用crontab -e命令來創建計劃任務。為自己創建計劃任務無需使用-u參數,具體的實現效果的參數如crontab -l命令結果所示:

[[email protected] ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[[email protected] ~]# crontab -l
25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot

需要說明的是,除了用逗號(,)來分別表示多個時間段,例如“8,9,12”表示8月、9月和12月。還可以用減號(-)來表示一段連續的時間周期(例如字段“日”的取值為“12-15”,則表示每月的12~15日)。以及用除號(/)表示執行任務的間隔時間(例如“*/2”表示每隔2分鐘執行一次任務)。

如果在crond服務中需要同時包含多條計劃任務的命令語句,應每行僅寫一條。例如我們再添加一條計劃任務,它的功能是每周一至周五的凌晨1點鐘自動清空/tmp目錄內的所有文件。尤其需要注意的是,在crond服務的計劃任務參數中,所有命令一定要用絕對路徑的方式來寫,如果不知道絕對路徑,請用whereis命令進行查詢,rm命令路徑為下面輸出信息中加粗部分。

[[email protected] ~]# whereis rm
rm: /usr/bin/rm /usr/share/man/man1/rm.1.gz /usr/share/man/man1p/rm.1p.gz
[[email protected] ~]# crontab -e
crontab: installing new crontab
[[email protected] ~]# crontab -l
25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
0 1?* * 1-5 /usr/bin/rm -rf /tmp/*

在本節最后,劉遄老師再來啰嗦幾句在工作中使用計劃服務的注意事項。

在crond服務的配置參數中,可以像Shell腳本那樣以#號開頭寫上注釋信息,這樣在日后回顧這段命令代碼時可以快速了解其功能、需求以及編寫人員等重要信息。

計劃任務中的“分”字段必須有數值,絕對不能為空或是*號,而“日”和“星期”字段不能同時使用,否則就會發生沖突。

最后再啰嗦一句,想必讀者也已經發現了,諸如crond在內的很多服務默認調用的是Vim編輯器,相信大家現在能進一步體會到在Linux系統中掌握Vim文本編輯器的好處了吧。所以請大家一定要在徹底掌握Vim編碼器之后再學習下一章。

出現問題?大膽提問!

因讀者們硬件不同或操作錯誤都可能導致實驗配置出錯,請耐心再仔細看看操作步驟吧,不要氣餒~

Linux技術交流請加A群:560843(滿),B群:340829(推薦),C群:463590(推薦),點此查看全國群

*本群特色:通過口令驗證確保每一個群員都是《Linux就該這么學》的讀者,答疑更有針對性,不定期免費領取定制禮品。

本章節的復習作業(答案就在問題的下一行哦,用鼠標選中即可看到的~)

 

1.Vim編輯器的三種模式分別是什么?

答:命令模式、末行模式與輸入模式(也叫編輯模式或插入模式)。

2.怎么從輸入模式切換到末行模式?

答:需要先敲擊Esc鍵退回到命令模式,然后敲擊冒號(:)鍵后進入末行模式。

3.一個完整的Shell腳本應該哪些內容?

答:應該包括腳本聲明、注釋信息和可執行語句(即命令)。

4.分別解釋Shell腳本中$0與$3變量的作用。

答:在Shell腳本中,$0代表腳本文件的名稱,$3則代表該腳本在執行時接收的第三個參數。

5.if條件測試語句有幾種結構,最靈活且最復雜的是哪種結構?

答:if條件測試語句包括單分支、雙分支與多分支等三種結構,其中多分支結構是最靈活且最復雜的結構,其結構形式為if…then…elif…then…else…fi。

6.for條件循環語句的循環結構是什么樣子的?

答:for條件循環語句的結構為“for 變量名 in 取值列表 do 命令序列 done”,如圖4-20所示。

7.若在while條件循環語句中使用true作為循環條件,那么會發生什么事情?

答:因條件測試值永久為true,因此腳本中循環部分會無限地重復執行下去,直到碰到exit命令才會結束。

8.如果需要依據用戶的輸入參數執行不同的操作,最方便的條件測試語句是什么?

答:case條件語句。

9.Linux系統的長期計劃任務所使用的服務是什么,其參數格式是什么?

答:長期計劃任務需要使用crond服務程序,參數格式是“分、時、日、月、星期 命令”。

本文原創地址:http://www.52437949.com/chapter-04.html編輯:劉遄,審核員:暫無