Linux Shell 腳本編寫指南——第二章


本文為Linux Shell Scripting Tutorial (LSST) v2.0學習記錄


第二章:開始shell腳本編程

本章節(jié)學習目標:

  • 編寫你第一個shell 程序

  • 理解創(chuàng)建一個shell腳本的步驟

2.1 Bash shell(全稱Bourne again shell)

有關bash的創(chuàng)建歷史(來自維基百科):

Bourne shell是一個交互式的shell誓竿,由AT&T實驗室的史蒂夫在1977年發(fā)布磅网,位于大多數(shù)Unix系統(tǒng)上的/bin/sh,隨著時間的發(fā)展筷屡,GNU計劃的誕生伴隨著shell的開發(fā)涧偷,這個時候1987年布萊恩編寫了Bash,也就是Bourne again shell毙死,總的來說燎潮,Bash雖然是一個滿足POSIX規(guī)范的shell,但有很多拓展扼倘。

Bash就是shell确封,或者可以說是Linux系統(tǒng)的命令語言解釋器:

  • Bash式GNU計劃的產(chǎn)物
  • Linux的默認shell
  • 反向兼容UNIX系統(tǒng)的sh
  • 與Korn shell(ksh)以及C shell(csh)兼容
  • 在多平臺類似UNIX/dos/Windows都是可運行多個

BASH的提升特性

  • 命令行編輯
  • 命令行補全
  • 無限大小的命令歷史
  • 提示控制
  • 不限大小的array
  • 以2-64為基數(shù)的整數(shù)運算
  • ……

作者

  • Brian J. Fox authored the GNU Bash shell, in 1987.
  • Fox maintained Bash as the primary maintainer until 1993, at which point Chet Ramey took over.
  • Chet Ramey is the current maintainer of the GNU Bourne Again Shell and GNU Readline.

下載

2.2 shell命令

bash shell有兩種類型的命令:

  1. 內置命令
  2. 外部命令(在bin/目錄里面的命令)

bash和命令類型

bash接受以下幾種類型的命令:

  • 別名(例如ll
  • 關鍵詞(例如if
  • 函數(shù)(例如genpassword
  • 內置命令(例如pwd
  • 文件(例如/bin/date)

type命令

找出某個命令(ls)是內置命令還是外部命令:

new@Chevy-PC:~$ type ls
ls is aliased to `ls --color=auto'
# 顯示為外部命令

找出某個命令(command)是內置命令還是外部命令:

new@Chevy-PC:~$ type -a history
history is a shell builtin
# 顯示為內置命令

bash命令關鍵詞以及內置命令

2.3 Hello, World! 第一個shell腳本

創(chuàng)建一個shell腳本你需要經(jīng)過以下幾個步驟:

  1. 利用一個文本編輯器(例如vi)再菊,將你的指令寫入一個文本
  2. 保存該文本并退出
  3. 改變該文本的可執(zhí)行權限
  4. 測試該腳本并放入你的生產(chǎn)環(huán)境
  5. 最簡單的shell腳本就是一行代碼告訴計算機執(zhí)行一個命令

讓我們來熟悉vi的操作并創(chuàng)建第一個shell script

# 打開一個文件
vi first_script.sh

# 進入編輯模式
# 按Esc鍵爪喘,然后按I鍵就進入編輯模式

# 進入命令模式
# 按Esc鍵就進入命令模式

# 保存文件
# 按Esc鍵然后輸入:w
# 或者按Esc鍵然后輸入:w first_script.sh

# 保存并退出文件
# 按Esc鍵然后輸入:wq
# 或者按Esc鍵然后輸入:x

# 跳到某一行
# 按Esc鍵然后輸入:x, x代表第幾行

# 搜索一個字符
# 按Esc鍵然后輸入/str, str代表該字符

# 退出vi(不保存)
# 按Esc鍵然后輸入:q

# 讓我們來編輯第一個腳本,輸入以下字符并保存退出
#!/bin/bash
echo "Hello, World!" 
echo "Knowledge is power."

# 將該文件改為可以執(zhí)行文件并執(zhí)行
new@Chevy-PC:~$ chmod 777 first_script.sh
new@Chevy-PC:~$ ./first_script.sh
Hello, World!
Knowledge is power.

Shebang

在腳本的第一行纠拔,我們需要告訴系統(tǒng)用哪種程序來運行這個腳本腥放,寫法為#!/path_to_binaries,我們一般稱其為Shebang或者bang行[1]

在bash腳本里面第一行我們一般寫成#!/bin/bash绿语,有些程序使用perl來運行的話秃症,就寫成#!/bin/perl

一個#!/bin.sh的腳本示例:

etc/init.d/policykit
#! /bin/sh
### BEGIN INIT INFO
# Provides:          policykit
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Create PolicyKit runtime directories
# Description:       Create directories which PolicyKit needs at runtime,
#                    such as /var/run/PolicyKit
### END INIT INFO

# Author: Martin Pitt <martin.pitt@ubuntu.com>

case "$1" in
  start)
        mkdir -p /var/run/PolicyKit
        chown root:polkituser /var/run/PolicyKit
        chmod 770 /var/run/PolicyKit
    ;;
  stop|restart|force-reload)
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 3
    ;;
esac

:

Shell注釋

在腳本里面#號后面的代碼會被忽略,這行代碼我們成為注釋吕粹,注釋可以幫助我們理解代碼并且便于修改:

#!/bin/bash
# A Simple Shell Script To Get Linux Network Information
# Vivek Gite - 30/Aug/2009
echo "Current date : $(date) @ $(hostname)"
echo "Network configuration"
/sbin/ifconfig

多行注釋可以使用HERE DOCUMENT 特性來進行注釋:

#!/bin/bash
echo "Adding new users to LDAP Server..."
<<COMMENT1
    Master LDAP server : dir1.nixcraft.net.in 
    Add user to master and it will get sync to backup server too
    Profile and active directory hooks are below
COMMENT1
echo "Searching for user..."

設置腳本權限

一個剛編輯完的腳本無法直接執(zhí)行种柑,你需要使用chmod命令給與其可執(zhí)行權限或者直接調用對應的命令來執(zhí)行,下面的操作具有同樣的效果:

chmod +x script.sh && ./script.sh
chmod 777 script.sh && ./script.sh

sh script.sh

使用ls -l可以查看一個文件的權限:

new@Chevy-PC:~$ ls -l first.sh
-rwxrwxrwx 1 new new 61 Jul 15 14:24 first.sh

更多chomd的操作可以使用man chmod查看

為什么不直接使用 scriptname 來調用腳本匹耕?為什么當工作目錄$PWD正好是scriptname 所在目錄時也不起作用聚请?因為一些安全原因,當前目錄./并不會被默認添加到用戶的$PATH路徑中稳其。因此需要用戶顯式使用 ./scriptname 在當前目錄下調用腳本驶赏。

腳本debug

在運行腳本的時候需要加上-x參數(shù)或者-xv參數(shù),又或者是將shebang行改成#!/bin.bash-x

使用內置命令

bash shell提供了debug選項既鞠,可以使用set命令打開或者關閉:

  • set -x:當腳本被執(zhí)行的時候展示命令及參數(shù)
  • set -v:當腳本被讀入的時候展示輸入行
  • set -n:讀入命令但不執(zhí)行(在檢查腳本是否有變量名重合的時候)
#!/bin/bash
### Turn on debug mode ###
set -x

# Run shell commands
echo "Hello $(LOGNAME)"
echo "Today is $(date)"
echo "Users currently on the machine, and their processes:"

### Turn OFF debug mode ###
set +x

# Add more commands without debug mode
#!/bin/bash
set -n # only read command but do not execute them
set -o noexec
echo "This is a test"
# no file is created as bash will only read commands but do not executes them 

本章節(jié)復習題

練習題1

按照下面代碼寫一個腳本并運行煤傍,觀察輸出:

# Script to print currently logged in users information, and current date & time.
clear
echo "Hello $USER"
echo -e "Today is \c ";date
echo -e "Number of user login : \c" ; who | wc -l
echo "Calendar"
cal
exit 0

? 輸出結果:

Hello new
Today is Tue Jul 16 15:34:58 CST 2019
Number of user login : 0
Calendar
     July 2019
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

練習題2

寫一個程序,打印出你最喜歡的電影名稱嘱蛋,同時在下一行打印出導演的名稱(以下是我自己的答案):

#!/bin/bash
# print moive and director

set -e

my_favorite_moive="gone_with_the_wind"

moive_director="not_known"

echo -e "my_favorite_moive is \c"; 
echo $my_favorite_moive
echo -e "the moive's director is \c"; 
echo $moive_director

exit 0
練習題3

寫一個shell腳本蚯姆,打印你的名字五续,在用戶按<ENTER>鍵之前保持等待狀態(tài):

#!/bin/bash
echo "Vivek Gite"
read -p "Press [Enter] key to continue..." fakeEnterKey
練習題4

列出十個內置命令和外部命令:

# builtin commands
history
break
cd
continue
eval
exit
grep
kill

# external commands
ls
gzip
練習題5

使用cd命令進入/etc/init.d目錄下,查看各種系統(tǒng)啟動腳本:

new@Chevy-PC:/bin$ cd /etc/init.d/
new@Chevy-PC:/etc/init.d$ ll
total 156
-rwxr-xr-x 1 root root 2269 Apr 22  2017 acpid*
-rwxr-xr-x 1 root root 4335 Mar 23  2018 apparmor*
-rwxr-xr-x 1 root root 2802 Nov 21  2017 apport*
-rwxr-xr-x 1 root root 1071 Aug 22  2015 atd*
-rwxr-xr-x 1 root root 1232 Apr 19  2018 console-setup.sh*
-rwxr-xr-x 1 root root 3049 Nov 16  2017 cron*
-rwxr-xr-x 1 root root  937 Mar 18  2018 cryptdisks*
-rwxr-xr-x 1 root root  978 Mar 18  2018 cryptdisks-early*
-rwxr-xr-x 1 root root 2813 Nov 16  2017 dbus*
-rwxr-xr-x 1 root root 4489 Jun 29  2018 ebtables*
-rwxr-xr-x 1 root root 3809 Feb 15  2018 hwclock.sh*
-rwxr-xr-x 1 root root 2444 Oct 25  2017 irqbalance*
-rwxr-xr-x 1 root root 1503 Feb 22  2018 iscsid*
-rwxr-xr-x 1 root root 1479 Feb 16  2018 keyboard-setup.sh*
-rwxr-xr-x 1 root root 2044 Aug 16  2017 kmod*
-rwxr-xr-x 1 root root  695 Dec  3  2017 lvm2*
-rwxr-xr-x 1 root root  571 Dec  3  2017 lvm2-lvmetad*
-rwxr-xr-x 1 root root  586 Dec  3  2017 lvm2-lvmpolld*
-rwxr-xr-x 1 root root 2378 Jun 17  2018 lxcfs*
-rwxr-xr-x 1 root root 2240 Jun  6  2018 lxd*
-rwxr-xr-x 1 root root 2653 Jun 26  2018 mdadm*
-rwxr-xr-x 1 root root 1249 Jun 26  2018 mdadm-waitidle*
-rwxr-xr-x 1 root root 2503 Feb 22  2018 open-iscsi*
-rwxr-xr-x 1 root root 1846 Mar 22  2018 open-vm-tools*
-rwxr-xr-x 1 root root 1366 Jan 17  2018 plymouth*
-rwxr-xr-x 1 root root  752 Jan 17  2018 plymouth-log*
-rwxr-xr-x 1 root root 1191 Jan 18  2018 procps*
-rwxr-xr-x 1 root root 4355 Dec 13  2017 rsync*
-rwxr-xr-x 1 root root 2864 Jan 15  2018 rsyslog*
-rwxr-xr-x 1 root root 1222 May 22  2017 screen-cleanup*
-rwxr-xr-x 1 root root 3837 Jan 26  2018 ssh*
-rwxr-xr-x 1 root root 5974 Apr 21  2018 udev*
-rwxr-xr-x 1 root root 2083 Aug 16  2017 ufw*
-rwxr-xr-x 1 root root 1391 Jul 18  2018 unattended-upgrades*
-rwxr-xr-x 1 root root 1306 May 16  2018 uuidd*

  1. SBCL - Shebang Scripts ?

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末龄恋,一起剝皮案震驚了整個濱河市疙驾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郭毕,老刑警劉巖它碎,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異显押,居然都是意外死亡扳肛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門煮落,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敞峭,“玉大人踊谋,你說我怎么就攤上這事蝉仇。” “怎么了殖蚕?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵轿衔,是天一觀的道長。 經(jīng)常有香客問我睦疫,道長害驹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任蛤育,我火速辦了婚禮宛官,結果婚禮上,老公的妹妹穿的比我還像新娘瓦糕。我一直安慰自己底洗,他們只是感情好,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布咕娄。 她就那樣靜靜地躺著亥揖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪圣勒。 梳的紋絲不亂的頭發(fā)上费变,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機與錄音圣贸,去河邊找鬼挚歧。 笑死,一個胖子當著我的面吹牛吁峻,可吹牛的內容都是我干的昼激。 我是一名探鬼主播庇绽,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼橙困!你這毒婦竟也來了瞧掺?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤凡傅,失蹤者是張志新(化名)和其女友劉穎辟狈,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夏跷,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡哼转,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了槽华。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壹蔓。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖猫态,靈堂內的尸體忽然破棺而出佣蓉,到底是詐尸還是另有隱情,我是刑警寧澤亲雪,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布勇凭,位于F島的核電站,受9級特大地震影響义辕,放射性物質發(fā)生泄漏虾标。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一灌砖、第九天 我趴在偏房一處隱蔽的房頂上張望璧函。 院中可真熱鬧,春花似錦基显、人聲如沸蘸吓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽美澳。三九已至,卻和暖如春摸航,著一層夾襖步出監(jiān)牢的瞬間制跟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人睦袖。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓致份,卻偏偏與公主長得像妈倔,于是被迫代替她去往敵國和親楼熄。 傳聞我的和親對象是個殘疾皇子疚察,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內容