在 Linux 系统下,Shell 指令码可以在各种不同的情形下帮到我们,例如展示资讯,甚至 自动执行特定的系统管理任务,建立简单的命令列工具等等。
在本指南中,我们将向 Linux 新手展示如何可靠地储存自定义的 shell 指令码,解释如何编写 shell 函式和函式库,以及如何在其它的指令码中使用函式库中的函式。
Shell 指令码要储存在何处
为了在执行你自己的指令码时不必输入指令码所在位置的完整或绝对路径,指令码必须被储存在 $PATH 环境变数所定义的路径里的其中一个。
使用下面的命令可以检视你系统中的 $PATH 环境变数:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
通常来说,如果在使用者的家目录下存在名为 bin 的目录,你就可以将 shell 指令码储存在那个目录下,因为那个目录会自动地被包含在使用者的 $PATH 环境变数中(LCTT 译注:在 Centos 6/7 下是这样的,在 Debian 8 下不是这样的,在 Ubuntu 16.04 下又是这样的) 。
因此,在你的主目录下建立 bin 目录吧(当然这里也可以用来储存 Perl 、 Awk 或 Python 的指令码,或者其它程式):
$ mkdir ~/bin
接著,建立一个名为 lib(libraries 的简写)的目录来存放你自己的函式库。你也可以在其中存放其它程式语言的函式库,如 C ,Python 等语言。在 lib 目录下建立另一个名为 sh 的目录,这个目录将被用来存放你的 shell 函式库:
$ mkdir -p ~/lib/sh
建立你自己的 Shell 函式和函式库
一个 shell 函式 就是在指令码中能够完成特定任务的一组命令。它们的工作原理与其他程式语言中的过程(LCTT 译注:可能指的是类似 SQL 中的储存过程之类的吧)、子例程、函式类似。
编写一个函式的语法如下:
函式名 () { 一系列的命令 }
( LCTT 校注:在函式名前可以加上 function 关键字,但也可省略不写)
例如,你可以像下面那样在一个指令码中写一个用来显示日期的函式:
showDATE() {date;}
每当你需要显示日期时,只需呼叫该函式的函式名即可:
$ showDATE
简单来说 shell 函式库也是一个 shell 指令码,不过你可以在一个函式库中仅储存其它 shell 指令码中需要呼叫的函式。
下面展示的是在我的 ~/lib/sh 目录下一个名为 libMYFUNCS.sh 的库函式:
#!/bin/bash
### Function to clearly list directories in PATH
showPATH() {
oldifs=”$IFS” ### store old internal field separator
IFS=: ### specify a new internal field separator
for DIR in $PATH
do
echo $DIR
done
IFS=”$oldifs” ### restore old internal field separator
}
### Function to show logged user
showUSERS() {
echo -e “Below are the user logged on the system:n”
w
}
### Print a user’s details
printUSERDETS() {
oldifs=”$IFS” ### store old internal field separator
IFS=: ### specify a new internal field separator
read -p “Enter user name to be searched:” uname ### read username
echo “”
### read and store from a here string values into variables
### using : as a field delimiter
read -r username pass uid gid comments homedir shell <<< "$(cat /etc/passwd | grep "^$uname")"
### print out captured values
echo -e "Username is : $usernamen"
echo -e "User's ID : $uidn"
echo -e "User's GID : $gidn"
echo -e "User's Comments : $commentsn"
echo -e "User's Home Dir : $homedirn"
echo -e "User's Shell : $shelln"
IFS="$oldifs" ### store old internal field separator
}
储存档案并且给指令码新增执行许可权。
如何从函式库中呼叫函式
要使用某个 lib 目录下的函式,首先你需要按照下面的形式 将包含该函式的函式库汇入到需要执行的 shell 指令码中:
$ . /path/to/lib
或
$ source /path/to/lib
(LCTT 译注:第一行的 . 和路径间必须是有空格的)
这样你就可以像下面演示的那样,在其它的指令码中使用来自 ~/lib/sh/libMYFUNCS.sh 的 printUSERDETS 函式了。
在下面的指令码中,如果要列印出某个特定使用者的详细资讯,你不必再一一编写程式码,而只需要简单地呼叫已存在的函式即可。
建立一个名为 test.sh 的新档案:
#!/bin/bash
### include lib
. ~/lib/sh/libMYFUNCS.sh
### use function from lib
printUSERDETS
### exit script
exit 0
储存这个档案,并使得这个指令码可被执行,然后执行它:
$ chmod 755 test.sh
$ ./test.sh