溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

適合系統(tǒng)管理新手的bash腳本編程有哪些

發(fā)布時(shí)間:2021-11-08 11:35:35 來(lái)源:億速云 閱讀:119 作者:小新 欄目:系統(tǒng)運(yùn)維

小編給大家分享一下適合系統(tǒng)管理新手的bash腳本編程有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

UNIX shell 實(shí)質(zhì)上是用戶(hù)、內(nèi)核和系統(tǒng)硬件之間的接口。在任何 UNIX 或 Linux 系統(tǒng)上,shell  都是非常重要的,是學(xué)習(xí)正確的系統(tǒng)管理和安全保護(hù)最關(guān)鍵的方面之一。shell 通常由 CLI 驅(qū)動(dòng),可以直接控制或破壞系統(tǒng)。本文討論的開(kāi)放源碼的 bash  shell 是***大、最實(shí)用、可擴(kuò)展性***的 shell 之一。在本文中,您將學(xué)習(xí) bash 腳本編程的基本技術(shù)、日常使用方法以及用它創(chuàng)建可靠的 shell  腳本的方法。

常用縮略詞

·API:應(yīng)用程序編程接口

·CLI:命令行接口

·SNMP:簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議

bash shell 的歷史

Bourne Again Shell (bash) 誕生于 1987 年,是作為 GNU 項(xiàng)目開(kāi)發(fā)的,許多 Linux  發(fā)行版很快就采用了它。當(dāng)前,有許多不同的 bash 版本可免費(fèi)使用。

bash 的優(yōu)點(diǎn)之一是它具有內(nèi)置的安全特性。bash 會(huì)準(zhǔn)確地記錄用戶(hù)輸入的命令,并把記錄寫(xiě)到用戶(hù)主目錄中的隱藏文件 .bash_history  中。因此,如果實(shí)現(xiàn) bash,就很容易更緊密地跟蹤系統(tǒng)用戶(hù)。實(shí)際上,對(duì)于許多 Linux 系統(tǒng),bash 常常是預(yù)安裝的默認(rèn) shell 環(huán)境。

bash 的命令語(yǔ)法和關(guān)鍵詞源于 Korn shell (ksh) 和 C shell (csh) 的架構(gòu)和技術(shù)細(xì)節(jié)并做了改進(jìn)。另外,bash  的語(yǔ)法具有其他 shell 所沒(méi)有的許多擴(kuò)展。與其他 shell 相比,bash 中的整數(shù)計(jì)算更高效,而且 bash  可以更方便地重定向標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr)。

bash 還非常適合于安全性要求高的環(huán)境,它具有受限制的啟動(dòng)模式,可以把 shell 中的用戶(hù)限制為只能執(zhí)行一組確定的命令。可以通過(guò)編輯自己的 bash  shell 登錄控制文件(即 .bashrc、.bash_profile、.bash_logout 和 .profile 等隱藏文件)定制登錄  shell。

bash shell 的用法和功能

要想編寫(xiě)有效的 bash shell 腳本,就必須掌握在 shell 中執(zhí)行導(dǎo)航和日常任務(wù)的基本 bash 命令集。

bash 登錄過(guò)程

在登錄時(shí),用戶(hù)通常執(zhí)行一個(gè)全局概要文件和兩個(gè)個(gè)人文件(.bash_profile 和 .bashrc)。圖 1 顯示通常的過(guò)程。

適合系統(tǒng)管理新手的bash腳本編程有哪些

圖 1. bash shell 登錄過(guò)程


現(xiàn)在,看看 Linux 用戶(hù)典型的 .bash_profile(清單 1)和 .bashrc(清單 2)腳本。這些腳本是從用戶(hù)的主目錄裝載的。

清單 1. 典型的 .bash_profile 文件

[fred.smythe@server01 ~]$ cat .bash_profile

# .bash_profile

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

# User specific environment and startup programs

export JAVA_HOME=/usr/java/default

export PATH=$JAVA_HOME/bin:$PATH

PATH=$PATH:$HOME/bin

export PATH

在 清單 2 中的 .bashrc 文件中,配置了一些用戶(hù)別名并裝載了全局 bashrc 文件(如果存在的話(huà))。

清單 2. 典型的 .bashrc 文件

[fred.smythe@server01 ~]$ cat .bashrc

# .bashrc

# User specific aliases and functions

alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

alias tc6='cd /opt/tomcat/6.0.13'

alias conf6='cd /opt/tomcat/6.0.13/conf'

alias bin6='cd /opt/tomcat/6.0.13/bin'

alias scr='cd /opt/tomcat/scripts'

alias reports='cd /opt/tomcat/reports'

alias temp6='cd /opt/tomcat/6.0.13/template'

# Source global definitions

if [ -f /etc/bashrc ]; then

. /etc/bashrc

fi

適合系統(tǒng)管理新手的bash腳本編程有哪些

圖 2. bash shell 登錄過(guò)程細(xì)節(jié)


在此之后,用戶(hù)就可以使用 bash shell 環(huán)境變量 $PATH 中指定的標(biāo)準(zhǔn)命令集。如果某個(gè)命令不在用戶(hù)的 $PATH  中,但是該用戶(hù)有執(zhí)行此命令的權(quán)限,那么必須使用完整的路徑,見(jiàn) 清單 3。

清單 3. bash shell 中的 $PATH 問(wèn)題示例

[fred.smythe@server01 ~]$ ifconfig -a

-bash: ifconfig: command not found

[fred.smythe@server01 ~]$ which ifconfig

/usr/bin/which: no ifconfig in (/usr/local/bin:/bin:/usr/bin:/home/fred.smythe/bin)

出現(xiàn)此問(wèn)題的原因是二進(jìn)制程序 ifconfig 不在用戶(hù)定義的 PATH 變量中。但是,如果知道此命令的完整路徑,就可以像 清單 4 這樣執(zhí)行它。

清單 4. 使用命令的完整路徑解決 bash shell 中的 $PATH 問(wèn)題

[fred.smythe@server01 ~]$ /sbin/ifconfig -a

eth0 Link encap:Ethernet HWaddr 00:50:56:96:2E:B3

inet addr:10.14.33.60 Bcast:10.14.33.255 Mask:255.255.255.0

清單 5 演示一種使用別名解決此問(wèn)題的方法。在 bash 腳本中,可能希望用完整路徑運(yùn)行命令,這取決于誰(shuí)將運(yùn)行腳本。

清單 5. 通過(guò)設(shè)置別名解決 bash shell 中的 $PATH 問(wèn)題

[fred.smythe@server01 ~]$ alias ifconfig='/sbin/ifconfig'

[fred.smythe@server01 ~]$ ifconfig

eth0 Link encap:Ethernet HWaddr 00:50:56:96:2E:B3

inet addr:10.14.33.60 Bcast:10.14.33.255 Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

forking

命令或 bash shell 本身可能啟動(dòng)(或生成)新的 shell 子進(jìn)程以執(zhí)行某一任務(wù),這稱(chēng)為  forking。當(dāng)這個(gè)新進(jìn)程(子進(jìn)程)正在執(zhí)行時(shí),父進(jìn)程仍然在運(yùn)行。如果父進(jìn)程先于子進(jìn)程死亡,那么子進(jìn)程就成了死進(jìn)程(也稱(chēng)為僵尸進(jìn)程  ),這常常會(huì)導(dǎo)致進(jìn)程或應(yīng)用程序掛起。因此,必須以非常規(guī)方法殺死或終止掛起的進(jìn)程。盡管父進(jìn)程可以訪(fǎng)問(wèn)其子進(jìn)程的進(jìn)程 ID 并向它傳遞參數(shù),但是反過(guò)來(lái)不行。當(dāng)  shell 腳本進(jìn)程退出或返回到父進(jìn)程時(shí),退出碼應(yīng)該是 0。如果是其他值,那么進(jìn)程很可能出現(xiàn)了錯(cuò)誤或問(wèn)題。

執(zhí)行的***一個(gè)命令的退出碼(echo $?)見(jiàn) 清單 6。

清單 6. 退出碼示例

# ls -ld /tmp

drwxrwxrwt 5 root root 4096 Aug 19 19:45 /tmp

[root@server01 ~]# echo $?

0 // Good command return of 0.

[root@server01 ~]# ls -l /junk

ls: /junk: No such file or directory

[root@server01 ~]# echo $?

2 // Something went wrong, there was an error, so return 2.

清單 7 演示 bash 環(huán)境中的父進(jìn)程和子進(jìn)程。

清單 7. bash 環(huán)境中的父進(jìn)程和子進(jìn)程示例

[root@server02 htdocs]# ps -ef | grep httpd

UID PID PPID C STIME TTY TIME CMD

root 8495 1 0 Jul26 ? 00:00:03 /usr/sbin/httpd -k start

apache 9254 8495 0 Aug15 ? 00:00:00 /usr/sbin/httpd -k start

了解自己的環(huán)境

如果輸入命令 env,就會(huì)看到 bash shell 默認(rèn)環(huán)境變量當(dāng)前設(shè)置的值,包括您的用戶(hù)名和 tty(終端)信息、$PATH  值和當(dāng)前工作目錄($PWD)。請(qǐng)看一下 清單 8。

清單 8. bash 環(huán)境的示例

[fred.smythe@server01 ~]$ env

HOSTNAME=server01

TERM=screen

SHELL=/bin/bash

HISTSIZE=1000

SSH_CLIENT=10.12.132.3 56513 22

SSH_TTY=/dev/pts/0

USER=fred.smythe

LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05

;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32

:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=

01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=

01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:

MAIL=/var/spool/mail/fred.smythe

PATH=/usr/local/bin:/bin:/usr/bin:/home/fred.smythe/bin

INPUTRC=/etc/inputrc

PWD=/home/fred.smythe

LANG=en_US.UTF-8

SHLVL=1

HOME=/home/fred.smythe

LOGNAME=fred.smythe

SSH_CONNECTION=10.14.43.183 56513 10.14.43.43 22

LESSOPEN=|/usr/bin/lesspipe.sh %s

G_BROKEN_FILENAMES=1

_=/bin/env

文件系統(tǒng)導(dǎo)航

可以使用 清單 9 所示的 bash 命令導(dǎo)航 Linux 文件系統(tǒng)。

清單 9. 在 bash 環(huán)境中導(dǎo)航

[fred.smythe@server01 ~]$ ls -l

total 0

[fred.smythe@server01 ~]$ cd /tmp

[fred.smythe@server01 tmp]$ df -ha .

Filesystem Size Used Avail Use% Mounted on

/dev/mapper/vg_root-lv_tmp

2.0G 68M 1.8G 4% /tmp

在此清單中,每次只執(zhí)行一個(gè)命令。但是,也可以使用分號(hào)(;)分隔符一起運(yùn)行它們,見(jiàn) 清單 10。

清單 10. 在 bash 中連續(xù)執(zhí)行命令

[fred.smythe@server01 tmp]$ ls -l ;cd /tmp;df -ha .

total 40

-rw-r----- 1 root root 1748 May 22 2009 index.html

-rw-r----- 1 root root 786 Aug 17 04:59 index.jsp

drwx------ 2 root root 16384 Jul 15 2009 lost+found

drwx------ 2 root root 4096 Aug 9 21:04 vmware-root

Filesystem Size Used Avail Use% Mounted on

/dev/mapper/vg_root-lv_tmp

2.0G 68M 1.8G 4% /tmp

[fred.smythe@server01 tmp]$

在 bash 命令行上,命令補(bǔ)全特性可以減少日常任務(wù)所需的輸入量。只需輸入命令的開(kāi)頭,然后按 Tab  鍵。注意,如果由于權(quán)限限制無(wú)法訪(fǎng)問(wèn)某個(gè)命令或文件,那么命令補(bǔ)全也無(wú)效。

在 bash 中獲得幫助

bash 提供幾種形式的幫助:

·man:

清單 11. bash 中的手冊(cè)頁(yè)示例

[fred.smythe@server01 tmp]$ man perl

PERL(1) Perl Programmers Reference Guide PERL(1)

NAME

perl - Practical Extraction and Report Language

SYNOPSIS

perl [ -sTtuUWX ] [ -hv ] [ -V[:configvar] ] -cw ] [ -d[t][:debugger] ] [ -D

[num- ber/list] ] [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ]

[ -Idir ] [ -m[-]module ] [ -M[-] module... ] [ -f ] [ -C [number/list] ]

[ -P ] [ -S ] [ -x[dir] ] [ -i[extension] ] [ -e command ] [ -- ]

[ program- file ] [ argument ]...

·whatis:

清單 12. bash 中的 whatis 命令示例

[fred.smythe@server01 tmp]$ whatis perl

perl (1) - Practical Extraction and Report Language

perl (rpm) - The Perl programming language

·apropos:

清單 13. bash 中的 apropos 示例

[root@server01 ~]# apropos perl | more

B (3pm) - The Perl Compiler

B::Asmdata (3pm) - Autogenerated data about Perl ops,

used to generate bytecode

B::Assembler (3pm) - Assemble Perl bytecode

·which:

清單 14. bash 中的 which 命令

[root@server01 ~]# which perl

/usr/bin/perl

bash shell 包含兩類(lèi)命令:內(nèi)部的內(nèi)置命令 和外部程序(或外部篩選器和命令,它們通常是自含的二進(jìn)制程序文件)。清單 15 說(shuō)明如何使用 alias  命令在 bash 中尋找內(nèi)置命令。

清單 15. 在 bash 中尋找內(nèi)置命令

[root@server01 ~]# man -k builtins| more

. [builtins] (1) - bash built-in commands, see bash(1)

: [builtins] (1) - bash built-in commands, see bash(1)

[ [builtins] (1) - bash built-in commands, see bash(1)

alias [builtins] (1) - bash built-in commands, see bash(1)

bash [builtins] (1) - bash built-in commands, see bash(1)

bg [builtins] (1) - bash built-in commands, see bash(1)

bind [builtins] (1) - bash built-in commands, see bash(1)

break [builtins] (1) - bash built-in commands, see bash(1)

builtin [builtins] (1) - bash built-in commands, see bash(1)

可以使用 type 命令在 bash 中尋找特定的命令,見(jiàn) 清單 16。

清單 16. 使用 type 命令尋找內(nèi)置命令

[root@apache-02 htdocs]# type lsof

lsof is /usr/sbin/lsof

[root@apache-02 htdocs]# type alias

alias is a shell builtin

清單 17 給出外部命令 lsof 的示例。此命令實(shí)際上是駐留在 Linux 文件系統(tǒng)中的二進(jìn)制文件;它是通過(guò)同名的包安裝的。

清單 17. 在 bash 中尋找外部命令詳細(xì)信息

[root@server01 ~]# which lsof

/usr/sbin/lsof

[root@server01 ~]# rpm -qa lsof-4.78-3.i386

[root@server01 ~]# rpm -qa lsof

lsof-4.78-3.i386

即時(shí) bash 腳本編程

bash shell ***大的特性之一是允許即時(shí)命令行腳本編程。比如 清單 18 中的示例,它設(shè)置一個(gè) shell  變量,檢查變量的值,如果值大于零,就自動(dòng)地執(zhí)行另一個(gè)命令。

清單 18. 用 bash 進(jìn)行即時(shí)腳本編程

[fred.smythe@server01 ~]$ DEBUG=1

[fred.smythe@server01 ~]$ test $DEBUG -gt 0 && echo "Debug turned on"

Debug turned on

下面是即時(shí)編寫(xiě)的 for 循環(huán)示例(見(jiàn) 清單 19)。注意,這里在 shell 提示下交互地輸入;在每個(gè) > 后面,輸入交互式 shell  腳本的下一行。

清單 19. 在 bash 中即時(shí)編寫(xiě)的 for 循環(huán)

$ for SVR in 1 2 3

> do

> echo server0$SVR.example.com

> done

server01.example.com

server02.example.com

server03.example.com

注意,也可以將此代碼作為分號(hào)分隔的連續(xù)命令予以運(yùn)行。

使用關(guān)鍵詞

for 命令并不是程序,而是稱(chēng)為關(guān)鍵詞 的特殊內(nèi)置命令。Linux 上一般 bash 版本的關(guān)鍵詞列表見(jiàn) 清單 20。

清單 20. bash 中的關(guān)鍵詞

true, false, test, case, esac, break, continue, eval, exec, exit, export, readonly,

return, set, shift, source, time, trap, unset, time, date, do, done, if, fi, else, elif,

function, for, in, then, until, while, select

在為 shell 變量選擇名稱(chēng)時(shí),應(yīng)該避免使用這些關(guān)鍵詞(也稱(chēng)為 bash shell 保留字)。

在 bash 中用管道輸送命令

bash shell 允許重定向 Linux 或 UNIX 系統(tǒng)上的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。請(qǐng)看 清單 21 中的示例。

清單 21. 在 bash 中用管道輸送命令

$ USER="fred.smythe"

$ echo -n "User $USER home is: " && cat /etc/passwd | grep $USER | awk -F: '{print $6}'

User fred.smythe home is: /home/fred.smythe

$

# Re-direction of standard output (>) of the date command to a file :

[root@server01 ~]# date > /tmp/today.txt

[root@server01 ~]# cat /tmp/today.txt

Thu Aug 19 19:38:33 UTC 2010

# Re-direction of standard input (<) to standard output (>) &hellip;

[root@server01 ~]# cat < /tmp/today.txt > /tmp/today.txt.backup

[root@server01 ~]# cat /tmp/today.txt.backup

Thu Aug 19 19:38:33 UTC 2010

復(fù)合命令行

復(fù)合命令行可以使用和組合標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤重定向和/或管道的多個(gè)實(shí)例,從而執(zhí)行具有較高準(zhǔn)確性的復(fù)雜操作。清單 22 提供一個(gè)示例。

清單 22. 在 bash 中執(zhí)行重定向的示例

# command1 < input_file1.txt > output_file1.txt

# command1 | command2 | command3 > output_file.log

例如,通過(guò)使用復(fù)雜的組合命令行,可以搜索找到的所有壓縮的錯(cuò)誤日志并統(tǒng)計(jì)錯(cuò)誤數(shù)量,由此查明 Apache 拒絕權(quán)限錯(cuò)誤的數(shù)量。

$ find ./ -name 'error_log.*.gz' | xargs zcat | grep 'Permission denied'| wc -l

3

編寫(xiě)高質(zhì)量的 bash 腳本

要想完成生產(chǎn)質(zhì)量或企業(yè)級(jí)的腳本編程,必須記住以下幾個(gè)要點(diǎn):

&middot;一定要用簡(jiǎn)短的標(biāo)題注釋腳本。

&middot;要加上足夠的注釋?zhuān)@樣以后就可以輕松地想起原來(lái)編寫(xiě)代碼的原因。請(qǐng)記住,腳本的***行必須是 #!/bin/bash 行。

&middot;應(yīng)該把腳本的操作記錄在日志文件中并加上日期和時(shí)間戳,以便日后檢查。輸出應(yīng)該很詳細(xì),應(yīng)該記錄成功消息并清楚地表述錯(cuò)誤消息或條件。記錄腳本的啟動(dòng)和停止時(shí)間也可能有意義??梢允褂? tee 命令把消息同時(shí)寫(xiě)到日志和標(biāo)準(zhǔn)輸出:

DATEFMT=`date "+%m/%d/%Y %H:%M:%S"`

echo "$DATEFMT: My message" | tee -a /tmp/myscript.log

&middot;如果腳本要寫(xiě)入日志文件,那么應(yīng)該創(chuàng)建新的日志文件,并在日志文件名中包含日期、小時(shí)、分鐘甚至秒。這樣的話(huà),在每次運(yùn)行腳本時(shí),可以使用簡(jiǎn)單的 find  命令循環(huán)和壓縮腳本的日志:

DATELOG=`date "+%m%d%y"`

LOGFILE="/data/maillog/mail_stats.log.$DATELOG"

# gzip the old mail_stats logs, older than 7 days

find /logs -type f -name "mail_stats.log.????????????" -mtime +7 | xargs gzip -9

# remove the old gzipped mail_stats logs after 30 days

find /logs -type f -name "mail_stats.log.*.gz" -mtime +30 -exec rm {} \;

# mail_log utility log resets

echo "" > /var/log/mail_stats.log.$DATELOG

&middot;應(yīng)該在腳本中加入錯(cuò)誤檢查邏輯,不要假設(shè)任何東西是正確的。這樣做會(huì)減少日后的很多麻煩和挫折。

&middot;盡可能在腳本中使用函數(shù)和 shell 腳本庫(kù)(通過(guò)導(dǎo)入另一個(gè)腳本)。這樣做可以重用經(jīng)過(guò)測(cè)試的可靠的代碼,避免重復(fù)編寫(xiě)腳本代碼并減少錯(cuò)誤。

&middot;要對(duì)用戶(hù)提供的輸入?yún)?shù)進(jìn)行篩選:

NUMPARAMETERS="$#"

if [ $NUMPARAMETERS != 3 ];then

echo "Insufficient number of parameter passed!”

echo “Please run script in format ./myscript.sh $1 $2 $3”

exit 2

fi

&middot;考慮在腳本中增加調(diào)試模式或功能 &mdash; 比如使用 set &ndash;x 命令。

&middot;在腳本中添加對(duì)某些事件發(fā)出警報(bào)的功能??梢允褂?SNMP 命令或聽(tīng)得到的鈴聲(echo x)發(fā)出警報(bào),然后用 mail 命令發(fā)送電子郵件。

&middot;如果用戶(hù)將像使用交互式菜單那樣使用您編寫(xiě)的腳本,那么要考慮用戶(hù)的環(huán)境 shell  和他們有權(quán)訪(fǎng)問(wèn)的命令。如果不確定,那么腳本中的所有命令都應(yīng)該使用完整路徑。

&middot;在 bash shell 腳本中添加獨(dú)特的返回碼。這樣的話(huà),在編寫(xiě)大腳本時(shí),可以根據(jù)返回碼輕松地找到發(fā)生錯(cuò)誤或問(wèn)題的準(zhǔn)確位置:

if [ “$ERRCHECK” != “” ];then

echo “Error Detected : $ERRCHECK ! Cannot continue, exit $EXITVAL value”

exit $EXITVAL

fi

&middot;在試驗(yàn)室環(huán)境中,針對(duì)可能出現(xiàn)的所有情況全面測(cè)試腳本。還應(yīng)該讓其他用戶(hù)對(duì)腳本執(zhí)行測(cè)試,讓他們故意嘗試 “破壞” 腳本。

&middot;如果腳本操作來(lái)自用戶(hù)或數(shù)據(jù)輸入文件的輸入數(shù)據(jù),那么一定要全面篩選、檢查和檢驗(yàn)輸入數(shù)據(jù)。操作數(shù)據(jù)列表的腳本應(yīng)該可以處理多個(gè)不同的數(shù)據(jù)列表集。

&middot;對(duì)于長(zhǎng)時(shí)間運(yùn)行的腳本,考慮在腳本中添加超時(shí)功能,以便在 n 分鐘之后終止或停止腳本:

stty &ndash;icannon min 0 time 1800

&middot;在代碼中適當(dāng)?shù)剡M(jìn)行縮進(jìn),增加代碼的可讀性。

對(duì)于用于特殊用途的腳本,可能希望添加交互式警告提示消息,從而向用戶(hù)說(shuō)明腳本的用途。例如,清單 23 中的腳本獲取遠(yuǎn)程日志并創(chuàng)建一個(gè)報(bào)告電子郵件。

清單 23. 獲取并報(bào)告日志的簡(jiǎn)單 bash 腳本

#!/bin/bash

cd /data01/maillog

MAILSVRS=$(/bin/cat /data01/maillog/mail_servers)

DATELOG=`date "+%m%d%y"`

ALLMAILLOGS="/data01/maillog/all_svr_maillogs.$DATELOG"

MAILREPORT="/data01/maillog/all_svr_maillogs.report.$DATELOG"

MAILADDRESSES=$(/bin/cat /data01/maillog/addresses)

MAILADMINS="admin1@example.com, admin2@example.com"

MAILSTATSLOGALL="/data01/maillog/mailstats.log.all.$DATELOG"

DELDAYSLOGS=10

echo “Mail Report to $ MAILADMINS”

# 1 - Get some logs &hellip;

for svr in $MAILSVRS

do

if [ -e "/data01/maillog/$svr.maillog.$DATELOG.gz" ]; then

/bin/rm -f /data01/maillog/$svr.maillog.$DATELOG.gz

fi

done

# 2 - Combine all maillogs from all servers to onefile ($ALLMAILLOGS) ...

/bin/zcat server16.maillog.$DATELOG.gz server17.maillog.$DATELOG.gz

server18.maillog.$DATELOG.gz server19.maillog.$DATELOG.gz >>

$ALLMAILLOGS

# 3 - Run another script

/bin/cat $ALLMAILLOGS | /data01/maillog/mymailstats.pl | tee -a $MAILREPORT

# 4 - Get all of the mailstats logs to one log file to send by Email

/bin/cat /data01/maillog/mailstats.log.server*.$DATELOG > $MAILSTATSLOGALL

# Send the $MAILADMINS the mail reports

/bin/cat $MAILSTATSLOGALL | mail -s "ACME Servers Outbound Mail Servers

mailstats:$DATELOG" $MAILADMINS

bash 腳本編程中的變量、語(yǔ)法格式和結(jié)構(gòu)

在 bash 中,可以通過(guò)幾種方法定義和設(shè)置變量。清單 24 中的腳本給出這些 shell 變量聲明方法的示例。

清單 24. 定義 bash 變量

$ cat a.sh

#!/bin/bash

A="String Value 1"

B='String Value 2'

C=9675

D=96.75

export E="String Value 3"

# if the variable $F is not ALREADY set to a value, assign "String Value 4" ...

F=${F:="String Value 4"}

echo "A=$A"

echo "B=$B"

echo "C=$C"

echo "D=$D"

echo "E=$E"

echo "F=$F"

exit 0

$ ./a.sh

A=String Value 1

B=String Value 2

C=9675

D=96.75

E=String Value 3

F=String Value 4

收集用戶(hù)輸入

要想收集用戶(hù)輸入,應(yīng)該使用 read 語(yǔ)句并向用戶(hù)輸入分配一個(gè)變量,見(jiàn) 清單 25。

清單 25. 在 bash 腳本中獲取用戶(hù)輸入

$ cat prompt.sh

#!/bin/bash

echo "Please enter your first and last name:"

read ans

echo "Hellow $ans , welcome to bash scripting ...!"

exit 0

$ ./prompt.sh

Please enter your first and last name:

Joe Jackson

Hello Joe Jackson , welcome to bash scripting ...!

要想在 bash shell 腳本中使用函數(shù),可以使用 清單 26 所示的方法。

清單 26. 在 bash 中實(shí)現(xiàn)函數(shù)

$ cat function.sh

#!/bin/bash

funcOne() {

echo "Running function 1, with parameter $1"

date

echo "Current listing /tmp directory, last 3 lines"

ls -lrt /tmp | tail -3

}

echo "Hello World"

funcOne "Server01"

exit 0

$ ./function.sh

Hello World

Running function 1, with parameter Server01

Sun Aug 22 22:43:04 UTC 2010

Current listing /tmp directory, last 3 lines

-rw-r- 1 dsmith progdevel 12749743 Aug 16 20:32 files.tar.gz

drwxr-xr-x 2 jjones progdevel 4096 Aug 16 20:42 ff_hosting_files

-rw-r- 1 rhill heng 1440 Aug 22 19:07 myscript.log

也可以像 清單 27 這樣編寫(xiě)函數(shù)。

清單 27. bash 中的另一種函數(shù)定義

#!/bin/bash

function funcTwo () {

echo "Running function 2, with parameter $1"

date

echo "Current listing /var directory, last 3 lines"

ls -lrt /var | tail -3

}

funcTwo "Server02"

exit 0

$ ./function.sh

Running function 2, with parameter Server02

Sun Aug 22 22:53:16 UTC 2010

Current listing /var directory, last 3 lines

drwxrwxrwt 3 root root 4096 Aug 6 18:22 tmp

drwxr-xr-x 6 root root 4096 Aug 22 04:02 log

drwxrwxr-x 4 root lock 4096 Aug 22 04:22 lock

function 關(guān)鍵詞是可選的。惟一的規(guī)則是必須先定義函數(shù),然后才能在程序中使用它。調(diào)用函數(shù)的方法是調(diào)用它的名稱(chēng)并傳遞必需的或可選的輸入?yún)?shù)。

循環(huán)和決策

假設(shè)您需要在幾個(gè)服務(wù)器上執(zhí)行某些重復(fù)的工作。在 bash 中,可以使用 for 循環(huán)輕松地實(shí)現(xiàn)這個(gè)目標(biāo)。清單 28 給出代碼。

清單 28. 簡(jiǎn)單 for 循環(huán)的 bash 腳本編程示例

$SERVERS=”server01 server02 server03 server04 server05”

for i in $SERVERS

do

echo "Removing file from server: $i"

ssh $i rm -f /tmp/junk1.txt

done

bash 中的 while 循環(huán)可以重復(fù)執(zhí)行語(yǔ)句一定的次數(shù),或者一直執(zhí)行到滿(mǎn)足某一條件為止。清單 29 給出一個(gè)示例。

清單 29. 簡(jiǎn)單的 while 循環(huán)

LOOPCTR=1

while [ $LOOPCTR -lt 6 ]

do

echo “Running patch script for server0$LOOPCTR”

/data/patch.sh server0$LOOPCTR

LOOPCTR=`expr $LOOPCTR + 1`

done

bash 中的 case 語(yǔ)句可以用來(lái)測(cè)試多個(gè)條件或值并相應(yīng)地執(zhí)行操作。有時(shí)候,使用這種語(yǔ)句比嵌套的 for 循環(huán)或 if  語(yǔ)句更好,可以減少重復(fù)的代碼而且結(jié)構(gòu)更清楚。清單 30 給出一個(gè)簡(jiǎn)短的 case 語(yǔ)句,它根據(jù)變量 $key 的值調(diào)用函數(shù)。

清單 30. bash 中的 case 語(yǔ)句示例

case $key in

q) logit "Quit";

exit;;

1) echo “\tChecking Mail Servers”;

check_mail_servers;;

2) echo "\tChecking Web Servers";

check_web_servers;;

3) echo “\tChecking App Servers;

check_app_servers;;

4) echo “\tChecking Database Servers”;

check_database_servers;;

b) echo "Go Back to Main menu";

MENUFLAG="main";

main_menu;;

*) echo "$key invalid choice";

invalid;;

esac

bash 腳本編程的優(yōu)缺點(diǎn)

需要快速地完成某些任務(wù)嗎?如果您掌握了 bash,就可以非常輕松地編寫(xiě)***的 web 組件,可以大大減少所需的時(shí)間。bash  腳本編程不是編程語(yǔ)言或應(yīng)用程序。不需要編譯器,也不需要特殊的庫(kù)或軟件開(kāi)發(fā)環(huán)境。但是,bash shell  腳本的行為與應(yīng)用程序相似,甚至能夠執(zhí)行應(yīng)用程序可以完成的一些任務(wù)和工作。

從好的方面來(lái)說(shuō):

bash 提供快速開(kāi)發(fā),代碼便于修改。bash 腳本編程的基本方法幾乎不隨時(shí)間變動(dòng)。

一些編程語(yǔ)言的代碼規(guī)則或語(yǔ)法的變動(dòng)可能比較頻繁,與它們相比,bash 的語(yǔ)法相當(dāng)簡(jiǎn)單明了。

高級(jí) bash 特性向用戶(hù)提供比以前更強(qiáng)的能力(例如,紀(jì)元、函數(shù)、信號(hào)控制、多個(gè)擴(kuò)展、命令歷史、使用一維數(shù)組的方法)。

進(jìn)行 bash shell 腳本編程只需要 *nix bash shell。

從壞的方面來(lái)說(shuō),bash 代碼:

由 shell 執(zhí)行,然后傳遞給內(nèi)核,這個(gè)過(guò)程通常比編譯為純機(jī)器碼的二進(jìn)制程序慢。因此,bash shell  腳本編程可能不適用于某些應(yīng)用程序設(shè)計(jì)或功能。

是明文的,具有讀權(quán)限的任何人都可以輕松地讀取它們,而編譯的二進(jìn)制代碼是不可讀的。在對(duì)敏感數(shù)據(jù)進(jìn)行編碼時(shí),使用明文是很?chē)?yán)重的安全風(fēng)險(xiǎn)。

沒(méi)有特定的標(biāo)準(zhǔn)函數(shù)集,而許多現(xiàn)代編程語(yǔ)言有內(nèi)置的函數(shù),可以滿(mǎn)足各種編程需求。

以上是“適合系統(tǒng)管理新手的bash腳本編程有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI