后浪笔记一零二四

1. 内置函数

job命令可以显示当前运行在后台模式中的所有用户的进程(作业)。显示在方括号中的是作业号,它还会显示作业的当前状态以及对应的命令。利用jobs命令的-l选项,可以显示进程的PID。需要提醒的是:后台作业的结束状态可未必会一直等待到合适的时候才现身。当作业结束状态突然出现在屏幕上的时候,你可别吃惊啊。

2. shell的父子关系

刚进入命令窗口时所处的shell是其他shell的根shell。 在CLI提示符后输入/bin/bash命令时,会创建一个新的shell程序。这个shell程序被称为子shell。 子shell的父进程id就是父进程的进程id。在生成子shell进程时,只有部分父进程的环境被复制到子shell环境中。 可以使用exit命令退出当前shell。

bash命令行参数

参数 描述
-c string 从string中读取命令并进行处理
-i(interaction) 启动一个能够接受用户输入的交互shell
-l 以登录shell的形式启动
-r(restrict) 启动一个受限shell,用户会被限制在默认目录中
-s(standard) 从标准输入中读取命令

3. 内建命令和外部命令的区别(内建函数和外部函数的区别)

① 外部命令,也称为文件系统命令,是存在于bash shell之外的程序,它们并不是shell程序的一部分。 外部命令程序通常位于/bin, /usr/bin, /sbin, 或/usr/sbin中。 当外部命令执行时,会创建出一个子进程。这种操作被称为衍生(forking)

1
2
3
4
$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
dacheg   30859 28792  0 16:00 pts/4    00:00:00 bash
dacheg   30868 30859  2 16:00 pts/4    00:00:00 ps -f

② 内建命令 内建命令不需要使用子进程来执行。它们已经和shell编译成了一体,作为shell工具的组成部分存在。cd和exit命令都內建于bash shell。可以利用type命令来了解某个命令是否是內建的。注意,有些命令有多种实现。例如echo和pwd既有內建命令也有外部命令。要查看命令的所有实现,使用type命令的-a选项。注意,which命令只显示外部命令文件。

4. 内建函数(内建命令)

  1. printf

  2. trap

  3. readonly: 相当于C中的const,readonly将变量设为只读模式

  4. unset: 删除变量或函数

  5. set: 设置新的位置参数

  6. shift: 从左侧开始截取位置参数

  7. export:

  8. exit:

  9. return:

  10. test: 既是bash的内建命令,也是keyword

  11. history: 查看最近用过的命令列表,可以修改HISTSIZE环境变量的值来设置history中保存的历史命令数。 !!唤醒最近执行的那条命令,!2000执行编号为2000的那条命令。 在退出shell的时候,会将该shell中之前执行的所有命令写入到.bash_history文件中,如果要实现强制写入,需要使用-a参数。 默认情况下,只有在打开命令行窗口的时候才会读取.bash_history文件中的内容,如果想强制读取,需要使用-n参数。 alias: 查看当前可用的别名,使用-p参数。注意,因为alias命令属于內建命令,所以别名仅仅在它所定义的shell进程中才有效。

  12. exec: exec [-cl] [-a name] [command [arguments …]] [redirection …] Replace the shell with the given command.

        Execute COMMAND, replacing this shell with the specified program.
        ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified, 
        any redirctions(重定向) take effect in the current shell.
    
        Options:
          -a name        pass NAME as the zeroth argument to COMMAND
          -c             execute COMMAND with an empty environment
          -l             place a dash(冲撞) in the zeroth(第零) argument to COMMAND
    
        If the command cannot be executed, a non-interactive shell exits, unless
        the shell option `execfail` is set.
    
        Exit Status:
        Returns success unless  COMMAND is not found or a redirection error occurs.
    
  13. 使用set改变脚本的运行时配置

set -u 或者set -o nounset: 执行脚本的时候,如果遇到不存在的变量,bash默认忽略它。而set -u可以实现不忽略。

set -x 或者set -o xtrace:默认情况下,脚本执行后,屏幕只显示运行结果,没有其他内容。如果多个命令连续运行,它们的运行结果会连续输出。有时会分不清,某一段内容是什么命令产生的。这个时候就可以使用set -x,它会打印出输出所对应的命令。

set -e 或者set -o errexit:如果脚本里面有运行失败的命令(返回值非0),bash默认会继续执行后面的命令。使用set -e之后,如果遇到运行失败的命令,直接退出脚本的执行。

  1. read命令 从标准输入(键盘)或另一个文件描述符中接受输入。在收到输入后,read命令会将数据放进一个变量。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ cat test 
#!/bin/bash
# testing the read command
#
echo -n "Enter your name: "
read name
echo "Hello $name, welcome to my program."
$ ./test 
Enter your name: hehe
Hello hehe, welcome to my program.

实际上,read命令包含了-p选项,允许你直接在read命令行指定提示符。read -p "Please enter your age:" age。read命令会将提示符后输入的所有数据分配给单个变量,要么你就指定多个变量。输入的每个数据值都会分配给变量列表中的下一个变量。如果变量数量不够,剩余的数据就全部分配给最后一个变量。也可以在read命令行中不指定变量。如果是这样,read命令会将它收到的任何数据都放进特殊变量REPLY中。

使用read命令时要当心。脚本很可能会一直苦等着脚本用户的输入。如果不管是否有数据输入,脚本都必须继续执行,你可以用-t选项来指定一个计时器。-t选项指定了read命令等待输入的描述。当计时器过期后,read命令会返回一个非零退出状态码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ cat test 
#!/bin/bash
# timing the date entry
#
if read -t 5 -p "Please enter your name: " name
then 
	echo "Hello $name, welcome to my script"
else
	echo
	echo "Sorry, too slow! "
fi
$ ./test 
Please enter your name: 
Sorry, too slow! 

也可以不对输入过程计时,而是让read命令来统计输入的字符数。当输入的字符达到预设的字符数时,就自动退出,将输入的数据赋给变量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ cate test
#!/bin/bash
# getting just one character of input
# 
read -n1 -p "Do you want to continue [Y/N]? " answer
case $answer in
Y | y) echo
       echo "fine, continue on..." ;;
N | n) echo 
       echo OK, goodbye
       exit;;
esac
echo "This is the end of the script"

-s选项可以避免在read命令中输入的数据出现在显示屏上(实际上,数据会被显示,知识read命令会将文本颜色设成跟背景颜色一样)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ cat test
#!/bin/bash
# hiding input data from the monitor
#
read -s -p "Enter your password: " pass
echo
echo "Is your password really $pass? "
$
$ ./test
Enter your password:
Is your password really T3st1ng?

最后,也可以用read命令来读取linux系统上文件里保存的数据。每次调用read命令,它都会从文件中读取一行文本。当文件中再没有内容时,read命令会退出并返回非零退出状态码。其中最难的部分是将文件中的数据传给read命令。最常见的方法是对文件使用cat命令,将结果通过管道直接传给含有read命令的while命令。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ cat test
#!/bin/bash
# reading data from a file
#
count=1
cat test | while read line
do 
    echo "Line $count: $line"
    count=$[ $count + 1 ]
done
echo "Finished processing the file"
$
$ cat test
The quick brown dog jumps over the lazy fox.
This is a test, this is only a test.
O Romeo, Romeo! Wherefore art thou Romeo?
  1. select命令
1
2
3
4
select variable in list
do
    commands
done

list参数是由空格分割的文本选项列表,这些列表构成了整个菜单。select命令会将每个列表项显示成一个带编号的选项,然后为选项显示一个由PS3环境变量定义的特殊提示符。

 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
32
33
34
35
36
37
#!/bin/bash
# using select in the menu

function diskspace {
	clear
	df -k
}

function whoseon {
	clear
	who
}

function memusage {
	clear
	cat /proc/meminfo
}

# 注意,在ubuntu系统中,PS3和select关键字没有关联。
# PS3="Enter option:  "
select option in "Display disk space" "Display logged on users" "Display memory usage" "Exit program"
do
	case $option in
	"Exit program")
		break ;;
	"Display disk space")
		diskspace ;;
	"Display logged on users")
		whoseon ;;
	"Display memory usage")
		memusage ;;
	*)
		clear
		echo "Sorry, wrong selection" ;;
	esac
done
clear

5. 外部函数(外部命令)

  1. mktemp命令可以在/tmp目录中创建一个唯一的临时文件。shell会创建这个文件,但不用默认的umask值。它会将文件的读和写权限分配给文件的属主,并将你设成文件的属主。
 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
# 1. 创建本地临时文件(在当前目录下创建)
$ mktemp testing.XXXXXX
testing.DDdEL9
$ ls -al testing*
-rw------- 1 dacheg dacheg 0 9月   6 09:31 testing.DDdEL9

# 2. 在/tmp目录创建临时文件
# 使用mktemp的-t选项,会返回临时文件的全路径
$ mktemp -t test.XXXXXX
/tmp/test.XG3374

# 3. 创建临时目录
# -d选项告诉mktemp命令来创建一个临时目录而不是临时文件。
$ cat test
#!/bin/bash
# using a temporary directory
tempdir=$( mktemp -d dir.XXXXXX )
cd $tempdir
tempfile1=$( mktemp temp.XXXXXX )
tempfile2=$( mktemp temp.XXXXXX )
exec 7> $tempfile1
exec 8> $tempfile2
echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile" >&7
echo "This is a test line of data for $tempfile" >&8
  1. tee,T型接头 tee命令相当于管道的一个T型接头。它将从STDIN过来的数据同时发往两处。一处是STDOUT,另一处是tee命令行所指定的文件名。
1
2
3
4
# 默认情况下,tee命令会在每次使用时覆盖输出文件的内容
$ who | tee testfile
# 如果你想将数据追加到文件中,必须用-a选项。
$ date | tee -a testfile
  1. nohup 有时你想在终端会话中启动shell脚本,然后让脚本一直以后台模式运行直到结束,即使你退出了终端会话。这可以用nohup命令来实现。nohup命令运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号。这会在退出终端会话时阻止进程退出。和普通后台进程一样,shell会给命令分配一个作业号,linux系统会为其分配一个PID号。区别在于,当你使用nohup命令时,如果关闭该会话,脚本会忽略终端会话发过来的SIGHUP信号。由于nohup命令会解除终端与进程的关联,进程也就不再同STDOUT和STDERR联系在一起。为了保存该命令产生的输出,nohup命令会自动将STDOUT和STDERR的消息重定向到一个名为nohup.out的文件中。

6. 自定义函数

① 基本的脚本函数 有两种格式可以用来在bash shell脚本中创建函数。第一种格式采用关键字function,后跟分配给该代码块的函数名。

1
2
3
function name {
    commands
}

name属性定义了赋予函数的唯一名称。脚本中定义的每个函数都必须有一个唯一的名称。commands是构成函数的一条或多条bash shell命令。在调用该函数时,bash shell会按命令在函数中出现的顺序依次执行,就像在普通脚本中一样。

第二种格式更接近于c语言中定义函数的方式:

1
2
3
name() {
    commands
}

要在脚本中使用函数,只需要像其他shell命令一样,在行中指定函数名就行了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ cat test
#!/bin/bash
# using a function in a script
function func1 {
    echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
    func1
    count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script"

每次引用函数名func1时,bash shell会找到fun1函数的定义并执行你在那里定义的命令。函数定义不一定非得是shell脚本中首先要做的事,但一定要小心。如果在函数被定义之前使用它,你会收到一条错误消息。函数名必须是唯一的,否则会出现问题。如果你重定义了函数,新定义会覆盖原来函数的定义,这一切不会产生任何错误信息。

② 返回值 bash shell会把函数当做一个小型脚本,运行结束时会返回一个退出状态码。有3种不同的方法来为函数生成退出状态码。

  1. 默认退出状态码 默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码。

  2. 使用return命令 bash shell使用return命令来退出函数并返回特定的退出状态码。return命令允许指定一个整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设置函数退出状态码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ cat test
#!/bin/bash
# usint the return command in a function
function db1 {
    read -p "Enter a value: " value
    echo "doubling the value"
    return $[ $value * 2 ]
}
db1
echo "The new value is $?"

db1函数会将$value变量中的用户输入的值翻倍,然后用return命令返回结果。脚本用$?变量显示了该值。但当用这种方法从函数中返回值时,要小心了。记住下面两条技巧来避免这个问题: 第一 记住,函数一结束就取返回值; 第二 记住,退出状态码必须是0~255; 如果在用$?变量提取函数返回值之前执行了其他命令,函数的返回值就会丢失。

return 和 exit的区别:return用于函数内部,它在执行后会退出当前函数,并将返回值和控制权交给调用函数的对象。exit在执行后会结束整个程序,并将返回值和控制权交还给操作系统。

  1. 使用函数输出 正如可以将命令的输出保存到shell变量中一样,你也可以对函数的输出采用同样的处理办法。可以用 这种技术来获取任何类型的函数输出,并将其保存到变量中: result=$(db1) 这个命令会将db1函数的输出赋给$result变量。下面是在脚本中使用这种方法的例子。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ cat test
#!/bin/bash
# using the echo to return a value
function db1 {
    read -p "Enter a value: " value
    echo $[ $value * 2 ]
}
result=$(db1)
echo "The new value is $result"
$
$ ./test
Enter a value: 200
The new value is 400

这个例子中演示了一个不易察觉的技巧。你会注意到db1函数实际上输出了两条消息。read命令输出了一条简单的消息来向用户询问输入值。bash shell脚本非常聪明,并不将其作为STDOUT输出的一部分,并且忽略掉它。如果你用echo语句生成这条消息来向用户查询,那么它与会输出值一起被读进shell变量中。

③ 在函数中使用变量

  1. 向函数传递参数 bash shell会将函数当做小型脚本来对待。这意味着你可以像普通脚本那样向函数传递参数。函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在$0变量中定义,函数命令行上的任何参数都会通过$1,$2等定义。也可以用特殊变量$#来判断传递给函数的参数数目。在脚本中指定函数时,必须将参数和函数放在同一行,像这样:func1 $value1 10。然后函数可以用参数环境变量来获得参数值。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ cat test
#!/bin/bash
# passing parameters to a function
function addem {
    if [ $# -eq 0 ] || [ $# -gt 2 ]
    then 
        echo -1
    elif [ $# -eq 1 ]
    then
        echo $[ $1 + $1 ]
    else
        echo $[ $1 + $2 ]
    fi
}
echo -n "Adding 10 and 15: "
value=$(addem 10 15)
echo $value
echo -n "Let's try adding just one number: "
value=$(addem 10)
echo $value
echo -n "Now trying adding on numbers: "
value=$(addem)
echo $value

注意:由于函数使用特殊参数环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$ cat badtest
#!/bin/bash
# trying to access script parameters inside a function
function badfunc {
    echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
    # 这里应该使用value=$(badfunc $1 $2)
    value=$(badfunc)
    echo "The result is $value"
else 
    echo "Usage: badtest a b"
fi
$
$ ./badtest
Usage: badtest a b
$ ./badtest 10 15
./badtest: * : syntax error: operand expected (error token is "*")
  1. 函数中处理变量

给shell脚本程序员带来麻烦的原因之一就是变量的作用域。作用域是变量可见的区域。函数中定义的变量与普通变量的作用域不同。也就是说,对脚本的其他部分而言,它们是隐藏的。函数使用两种类型的变量:全局变量和局部变量。

全局变量是在shell脚本中任何地方都有效的变量。如果你在脚本的主体部分定义了一个全局变量,那么可以在函数内读取它的值。类似地,如果你在函数内定义了一个全局变量,可以在脚本的主体部分读取它的值。默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可在函数内正常访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ cat test
#!/bin/bash
# using a global variable to pass a value
function db1 {
    value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is: $value"
$ 
$ ./test
Enter a value: 450
The new value is: 900

$value变量在函数外定义并被赋值。当db1函数被调用时,该变量及其值在函数中都依然有效。如果变量在函数内被赋予了新值,那么在脚本中引用该变量时,新值也依然有效。但这其实是危险的,尤其是如果你想在不同的shell脚本中使用函数的话。它要求你清清楚楚地知道函数中具体使用了哪些变量,包括那些用来计算非返回值的变量。这里有个例子可说明事情是如何搞砸的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat badtest
#!/bin/bash
# demonstrating a bad use of variable
function func1 {
    temp=$[ $value + 5 ]
    result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then 
    echo "temp is larger"
else 
    echo "temp is smaller"
fi
$
$ ./badtest
The result is 22
temp is larger

由于函数中用到了$temp变量,它的值在脚本中使用时受到了影响,产生了意想不到的后果。

函数内部使用的任何变量都可以被声明成局部变量。要实现这一点,只要在变量声明的前面加上local关键字就可以了。 local temp。也可以在变量赋值语句中使用local关键字:local temp=$[ $value + 5 ]

local关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名字的变量,那么shell将会保持这两个变量的值是分离的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ cat test
#!/bin/bash
#demonstrating the local keyword
function func1{
    local temp=$[ $value + 5 ]
    result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
    echo "temp is larger"
else 
    echo "temp is smaller"
fi

④ 数组变量和函数

  1. 向函数传递数组参数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ cat badtest
#!/bin/bash
# trying to pass an array variable
function testit {
    echo "The parameters are: $@"
    thisarray=$1
    echo "The received array is ${thisarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
testit $myarray
$
$ ./badtest
The original array is: 1 2 3 4 5
The parameters are: 1
The received array is 1

如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ cat test
#!/bin/bash
# array variable to function test
function testit {
    local newarray
    newarray=($(echo "$@"))
    echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}

该脚本用$myarray变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数据变量。在函数内部,数据仍然可以像其他数组一样使用。

  1. 从函数返回数组

从函数里向shell脚本传回数组变量也用类似的方法。函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ cat test
#!/bin/bash
# returning an array value
function arraydblr {
    local origarray
    local newarray
    local elements
    local i
    # ()表示数组
    origarray=($(echo "$@"))
    newarray=($(echo "$@"))
    elements=$[ $# - 1 ]
    for (( i = 0; i <= $elements; i++ ))
    {
        newarray[$i]=$[ ${origarray[$i]} * 2 ]
    }
    echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
# 把函数的返回值封装成一个数组(返回值是一个字符串)
result=($(arraydblr $arg1))
echo "The new array is: ${result[*]}"

该脚本用$arg1变量将数组值传给arraydblr函数。arraydblr函数将该数组重组到新的数组变量中,生成该输出数组变量的一个副本。然后对数据元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。arraydblr函数使用echo语句来输出每个数组元素的值。脚本用arraydblr函数的输出来重新生成一个新的数组变量。

7. 常见库

使用函数可以在脚本中省去一些输入工作,这一点是显而易见的。但如果你碰巧要在多个脚本中使用同一段代码呢?显然,为了使用一次而在每个脚本中都定义同样的函数太过麻烦。有个办法能解决这个问题!bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。

第一步:创建一个包含脚本中所需函数的公用库文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ cat myfuncs
# my script functions
function addem {
    echo $[ $1 + $2 ]
}
function multem {
    echo $[ $1 * $2 ]
}
function divem {
    if [ $2 -ne 0 ]
    then
        echo $[ $1 / $2 ]
    else
        echo -1
    fi
}

第二步:在用到这些函数的脚本文件中包含myfuncs库文件。 从这里开始,事情就变复杂了。问题出在shell函数的作用域上。和环境变量一样,shell函数仅在定义它的shell会话内有效。如果你在shell命令行界面的提示符下运行myfuncs shell脚本,shell会创建一个新的shell并在其中运行这个脚本。它会为那个新shell定义这三个函数,但当你运行另外一个要用到这些函数的脚本时,它们是无法使用的。

这同样适用于脚本。如果你尝试像普通脚本文件那样运行库文件,函数并不会出现在脚本中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ cat badtest
#!/bin/bash
# using a library file the wrong way
# ./myfuncs是外部命令,所以会创建一个新的bash来运行它。
./myfuncs
result=$(addem 10 15)
echo "The result is $result"
$
$ ./badtest
./badtest: addem: command not found

使用函数库的关键在于source命令。source命令会在当前shell上下文中执行命令,而不是创建一个新shell。可以用source命令来在shell脚本中运行库文件脚本。这样脚本就可以使用库中的函数了。

source命令有个快捷的别名,称作点操作符(dot operator)。要在shell脚本中运行myfuncs库文件,只需添加下面这行:. ./myfuncs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ cat test
#!/bin/bash
# using functions defined in a library file
. ./myfuncs
value1=10
value2=5
result1=$(addem $value1 $value2)
result2=$(multem $value1 $value2)
result3=$(divem $value1 $value2)
echo "The result of adding them is: $result1"
echo "The result of multiplying them is: $result2"
echo "The result of dividing them is: $result3" 

下载及安装shtool函数库

首先是将GNU shtool库下载并安装到你的系统中,这样你才能在自己的shell脚本中使用这些库函数。要完成这项工作,可以使用FTP客户端或者图形化桌面中的浏览器。shtool软件包的下载地址是:ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz。将文件shtool-2.0.8.tar.gz下载到下载目录中。

构建库

shtool文件必须针对特定的linux环境进行配置。配置工作必须使用标准的configure和make命令,这两个命令常用于C编程环境。要构建库文件,只要输入:

1
2
$ ./configure
$ make

configure命令会检查构建shtool库文件所需要的软件。一旦发现了所需的工具,它会使用工具路径修改配置文件。 make命令负责构建shtool库文件。最终的结果(shtool)是一个完整的库软件包。你也可以使用make命令测试这个库文件。make test。测试模式会测试shtool库中所有的函数。如果全部通过测试,就可以将库安装到linux系统中的公用位置,这样所有的脚本就都能够使用这个库了。要完成安装,需要使用make命令的install选项。

shtool库函数

函数 描述
Arx 创建归档文件(包含一些扩展功能)
Echo 显示字符串,并提供了一些扩展构件
fixperm 改变目录树中的文件权限
install 安装脚本或文件
mdate 显示文件或目录的修改时间
mkdir 创建一个或更多目录
Mkln 使用相对路径创建链接
mkshadow 创建一棵阴影树
move 带有替换功能的文件移动
Path 处理程序路径
platform 显示平台标识
Prop 显示一个带有动画效果的进度条
rotate 转置日志文件
Scpp 共享的C预处理器
Slo 根据库的类别,分离链接器选项
Subst 使用sed的替换操作
Table 以表格的形式显示由字段分隔(field-separated)的数据
tarball 从文件和目录中创建tar文件
version 创建版本信息文件

要使用prop函数,只需要将希望监看的输出管接到shtool脚本就行了。

1
2
3
$ ls -al /usr/bin | shtool prop -p "waiting..."
waiting...
$

本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image