bash脚本切换管理员_初级系统管理员的Bash脚本

本文介绍了Bash脚本的基础知识,包括Bash的历史、特点、命令语法和关键字,以及如何编写高质量的Bash脚本。文章还探讨了Bash脚本的优缺点,并提供了实际的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UNIX Shell本质上是用户,内核和系统硬件之间的API。 在任何UNIX或Linux系统上,shell都是非常重要的,并且是了解适当的系统管理和安全性的最重要方面之一。 外壳程序通常由CLI驱动,实际上可以构成或破坏您的系统。 本文研究的开源bash shell是可用的最强大,实用和可扩展的shell之一。 在本文中,您将学习bash脚本的基本技术,其日常用法,以及使用bash来创建防子弹外壳脚本的方法。

bash外壳的历史

Bourne Again Shell(bash)始于1987年,当时它是作为GNU项目编写的,许多Linux发行版都Swift采用了它。 当前,bash的许多不同版本是免费提供的。

bash的更积极方面之一是其内置的安全功能。 Bash会记录用户正确键入的内容,并将其写入用户主目录中名为.bash_history的隐藏文件中。 因此,如果实施bash,则可以轻松地更紧密地跟踪系统用户。 实际上,对于许多Linux系统,通常将bash预安装为默认的shell环境。

Bash命令的语法和关键字已经在Korn shell(ksh)和C shell(csh)的体系结构和技术细节上进行了改进。 另外,bash的语法具有许多其他shell缺少的扩展。 在bash中,整数计算比在其他shell中更有效地完成,并且bash可以比旧的shell更轻松地重定向标准输出(stdout)和标准错误(stderr)。

Bash对于安全环境也是理想的选择,它具有受限制的启动模式,可以将用户在Shell中的能力限制在简短的,可确定的命令列表中。 开放进行修改,您可以编辑自己的一组bash shell登录控制文件(即隐藏文件,例如.bashrc,.bash_profile,.bash_logout和.profile)以自定义登录Shell。

bash shell的用途和功能

要编写有效的bash shell脚本,必须掌握基本的bash命令集,以用于在shell中执行导航和日常任务。

bash登录过程

登录后,用户通常具有全局配置文件以及已执行的两个个人文件(.bash_profile和.bashrc)。 图1显示了通常的处理流程。

图1. bash shell登录过程
bash shell登录过程插图

现在,看看典型的Linux用户的.bash_profile( 清单1 )和.bashrc( 清单2 )脚本。 这些脚本是从用户的主目录加载的。

清单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文件中,配置了一些用户别名,并且如果存在则加载全局bashrc文件。

清单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

系统级进程init产生了getty或agetty进程。 该过程依次调用/ bin / login程序,该程序显示熟悉的UNIX或Linux登录提示。 用户继续登录以访问系统,这时登录程序会生成一个新的bash shell。 当bash shell用户登录时,将按以下顺序发生以下事件:读取全局配置文件; 读取用户的个人bash配置文件; 然后读取用户的个人“ .bashrc”,这通常将设置别名,定义其他功能以及定义用户的各个环境变量。 最后,为bash用户提供一个bash shell提示,并读取并显示motd文件。 下面的图2是一个示例。

图2. Bash Shell登录过程细节
Bash Shell登录详细信息的插图

然后,用户可以从bash shell环境$ PATH变量中获得对他或她可用的标准命令程序集。 如果命令不在用户的$ PATH中,但是他或她有权执行该命令,则必须使用完整路径,如清单3所示。

清单3. bash shell中的$ PATH问题示例
[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)

当二进制程序ifconfig不在用户定义的PATH变量中时,就会出现此问题。 但是,如果您知道该命令的完整路径,则可以如清单4所示运行它。

清单4.使用命令的完整路径来克服bash shell中的$ PATH问题
[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显示了一种使用别名克服$ PATH问题的方法。 在bash脚本中,您可能希望使用完整路径来运行命令,具体取决于谁将运行预期的脚本。

清单5.设置别名以克服bash shell中的$ PATH问题
[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

分叉

当命令或bash shell本身启动(或产生)新的shell子进程来执行任务时,这称为forking 。 当这个新进程(子进程)正在执行时,父进程仍将运行。 如果父进程应该在子进程之前死亡,则子进程可以成为已失效的进程,也称为僵尸进程 ,通常导致挂起的进程或挂起的应用程序。 因此,该挂起的进程必须被终止或异常终止。 尽管父进程可以访问其子进程的进程ID,并因此可以将参数传递给它,但是相反的情况是错误的。 当Shell脚本进程退出或返回到父进程时,退出代码应为0 。 如果还有其他问题,则可能是该过程有错误或问题。

最后执行的命令的退出代码echo $? —如清单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环境中显示的父进程和子进程。

清单7. bash环境中的父子流程示例
[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

了解您的环境

如果键入命令env ,则会看到当前bash shell默认环境变量设置为什么,包括用户名和tty(终端)信息,$ PATH值以及当前的工作目录($ PWD)。 看一下清单8

清单8. bash环境的示例
[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

您可以使用清单9中所示的bash命令浏览Linux文件系统。

清单9:在bash环境中导航
[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

在清单中,一次发出了一个命令。 但是,您可以使用分号( ; )分隔符一起运行它们,如清单10所示。

清单10:以bash顺序执行命令
[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命令行上,命令完成可缩短日常任务所需的键入时间。 只需键入命令的开头,然后按Tab键即可。 请注意,如果由于权限限制而无法访问命令或文件,则命令完成功能将对您不起作用。

扑救自己

Bash提供了几种形式的帮助:

  • man (如清单11所示):
    清单11. bash中的手册页示例
    [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所示):
    清单12. bash中的whatis命令示例
    [fred.smythe@server01 tmp]$ whatis perl
    perl                 (1)  - Practical Extraction and Report Language
    perl                (rpm) - The Perl programming language
  • apropos (如清单13所示):
    清单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所示):
    清单14. bash中的which命令
    [root@server01 ~]# which perl
    /usr/bin/perl

bash shell包含两种类型的命令: 内置的内部命令和外部程序 (或外部过滤器和命令),它们通常是独立的二进制程序文件。 清单15显示了如何使用alias命令在bash中查找内置命令。

清单15.在bash中查找内置命令
[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)

要在bash中标识特定命令,请使用type命令,如清单16所示。

清单16.使用type命令查找内置命令
[root@apache-02 htdocs]# type lsof
lsof is /usr/sbin/lsof
[root@apache-02 htdocs]# type alias
alias is a shell builtin

清单17提供了一个lsof的示例,一个外部命令。 该命令实际上是Linux文件系统中的一个二进制文件。 通过相同名称的软件包安装。

清单17.在bash中查找外部命令详细信息
[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

即时执行Bash脚本

bash shell最强大的功能之一就是它能够即时运行命令行脚本。 考虑清单18中的示例,该示例设置一个shell变量,测试该变量的值,然后在该值大于零时以编程方式执行另一个命令。

清单18.使用bash即时编写脚本
[fred.smythe@server01 ~]$ DEBUG=1
[fred.smythe@server01 ~]$ test $DEBUG -gt 0 && echo "Debug turned on"
Debug turned on

这是即时编写for循环的示例(如清单19所示)。 请注意,这里是在shell提示符下交互式输入的; 在每个> ,键入交互式shell脚本的下一行。

清单19.在bash中即时编写的for循环
$ for SVR in 1 2 3
> do
> echo server0$SVR.example.com
> done
server01.example.com
server02.example.com
server03.example.com

请注意,您也可以将本代码作为由分号分隔的顺序命令来运行。

使用关键字

命令for不是程序,而是一种特殊的内置关键字 ,称为关键字 。 清单20显示了Linux上bash的平均分布中的关键字列表

清单20. bash中的关键字
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变量选择名称时,应避免使用这些关键字(即所谓的bash shell保留字) 。

bash中的管道命令

使用bash shell,您可以在Linux或UNIX系统上重定向标准输入,标准输出和标准错误。 考虑清单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 (>) … 
[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

复合命令行

复合命令行可以使用并组合标准输入,标准输出和标准错误重定向和/或管道的多个实例,以高精度和高精确度执行严格的操作。 清单22提供了一个示例。

清单22. bash内部重定向的示例
# command1 < input_file1.txt > output_file1.txt
# command1 | command2 | command3 > output_file.log

您可以使用复杂的组合命令行,例如,通过在所有找到的压缩错误日志中进行搜索并计算错误数量来查找Apache权限拒绝的错误。

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

编写高质量的bash脚本

要获得生产质量或企业级脚本,请牢记以下几点:

  • 始终用简短的标题注释您的脚本。
  • 对您的代码进行大量注释,以便以后可以轻松记住源代码按原样编写的原因。 请记住,脚本的第一行必须是#!/bin/bash行。
  • 将您的脚本操作写入具有日期和时间戳的日志文件,以供以后检查。 输出详细信息,记录成功消息,并清楚说明错误消息或条件。 记录脚本的开始和结束时间也是明智的。 使用tee命令,您可以同时附加到日志和标准输出:
    DATEFMT=`date "+%m/%d/%Y %H:%M:%S"`
    echo "$DATEFMT: My message" | tee -a /tmp/myscript.log
  • 如果您的脚本写入日志文件,请始终创建一个新的日志文件,并在新日志的文件名中包括日期,小时,分钟甚至秒。 然后,使用简单的find命令,您可以在每次运行脚本时轻松地旋转和压缩脚本自己的日志:
    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
  • 在脚本中构建错误检查逻辑,从不承担任何责任。 这样做将在以后节省大量的痛苦和悲伤。
  • 尽可能在脚本内合并使用功能和Shell脚本库(通过采购其他脚本)。 这样做可以重用经过测试和验证的代码,从而可以避免重复执行脚本代码并避免潜在的错误。
  • 过滤来自用户的输入参数:
    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
  • 考虑在脚本中添加调试模式或功能,例如,使用set –x命令。
  • 添加功能以警告或发送脚本中特定事件的陷阱。 您可以通过SNMP命令或可听的铃声( echo x )来执行此操作,然后使用mail命令发送电子邮件。
  • 如果要编写一个将用作交互式菜单的脚本,请考虑用户的环境外壳以及他们有权访问的命令。 如有疑问,请对脚本中的所有命令使用完整路径。
  • 将单独且唯一的返回码添加到bash shell脚本中。 当编写大型脚本时,您可以通过精确指出返回代码来轻松准确地确定发生错误或问题的位置:
    if [ “$ERRCHECK” != “” ];then
     	  echo “Error Detected : $ERRCHECK ! Cannot continue, exit $EXITVAL value” 
      exit $EXITVAL
    fi
  • 在实验室环境中针对所有可能的条件彻底测试脚本。 也让其他用户对脚本进行测试,并有意尝试“破坏”它们。
  • 如果您的脚本正在处理来自用户或数据输入文件的输入数据,请始终彻底过滤,检查和验证输入数据。 可以根据需要在数据列表上运行的脚本可以在多个不同的数据列表集上运行。
  • 对于将长时间运行的脚本,请考虑在脚本中放置超时功能以在n分钟后终止或停止:
    stty –icannon min 0 time 1800
  • 适当缩进代码以使其更具可读性。

对于为特定目的而编写的脚本,您可能需要添加交互式警告提示消息,以向用户提供有关脚本目的的信息。 例如, 清单23中的脚本检索远程日志并创建报告电子邮件。

清单23.用于检索日志并报告日志的简单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 …
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脚本中的变量,语法格式和结构

在bash中,有几种方法可用于定义和设置变量。 清单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

收集用户输入

为了收集用户输入,可以使用read语句并为用户输入分配一个变量,如清单25所示。

清单25.从bash脚本获取用户输入
$ 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脚本中使用函数,请使用清单26中所示的方法。

清单26.在bash中实现功能
$ 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中所示的函数。

清单27. bash中的替代函数定义
#!/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关键字是可选的。 唯一的规则是您需要先声明函数,然后才能在程序中稍后使用它。 您只需调用函数名称并将其传递给其他任何必需或可选的输入参数,即可调用该函数。

循环与决策

假设您需要在多台服务器上做一些重复的工作。 您可以轻松地在bash中使用for循环来快速完成工作。 清单28显示了代码。

清单28.一个简单的for循环的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循环使您可以执行给定次数的语句,或者直到满足特定条件为止。 清单29提供了一个示例。

清单29.一个简单的while循环
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语句使您可以测试多个条件或值并采取相应的措施。 使用这样的说法有时可以是一个更好的路线比嵌套for循环或if语句以减少重复的代码或只是为了更好的结构。 清单30显示了一个简短的case语句,该语句根据变量$key的条件来调用函数。

清单30. bash中的case语句示例
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脚本编写的优缺点

需要快速完成工作吗? 如果您精打细算,则可以减少编写最新的公司Gizmo Web小部件(如电锯通过温热黄油)所需的时间。 Bash脚本不是编程语言或应用程序。 不需要编译器,并且不需要特殊的库或软件开发环境即可工作。 但是bash shell脚本可以像应用程序一样运行,甚至可以执行应用程序可以执行的某些任务和工作。

在专业方面,bash提供:

  • 快速的开发时间和易于修改的代码。 bash脚本编写的基础不会随时间变化。
  • 与某些编程语言相比,语法相当简单,在某些编程语言中,编码或语法更改可能会频繁发生。
  • 高级bash功能(例如,时代,功能,信号控制,多个扩展,命令历史记录,使用一维数组的方式)为用户提供了比以前更大的功能。
  • 除了执行bash shell脚本所需的* nix bash shell外,没有什么其他的。

另一方面,bash代码:

  • 由外壳执行,然后传递给内核,通常比纯机器代码的已编译二进制程序要慢。 结果,对于某些应用程序设计或功能,bash shell脚本编写可能是不希望的。
  • 是明文或具有读取权限的任何人都可以轻松查看,而已编译的二进制文件不可读。 尝试对敏感数据进行编码时,这会带来巨大的安全风险。
  • 没有特定的标准功能集,而许多现代编程语言都具有满足各种编程需求的内在或内置功能。

结论

现在您已经掌握了bash shell脚本编写的基础知识,您必须保证仅将自己的力量用于更大的利益。 因此,出去并使用新发现的crontab,单行奇迹和交互式菜单保存* nix世界。 不要害怕成为“ bash”管理员!


翻译自: https://www.ibm.com/developerworks/aix/library/au-getstartedbash/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值