Linux 技术指南:VMware 安装与 Bash 脚本编写
1. VMware 客操作系统的安装
在进行 VMware 客操作系统的安装时,我们以 Fedora Core 5 为例。具体步骤如下:
1. 从 VMware 的社区网站下载 Fedora Core 5。
2. 将下载的文件移动到虚拟机目录。
3. 像解压 Debian 系统一样对其进行解压操作。
4. 通过文件菜单将其添加到我们的清单中。
在添加镜像时,VMware 管理控制台会提示我们输入一个唯一标识符(UUID),如图 9 - 8 所示。由于我们复制了 Fedora 5 且拥有构成该镜像的所有文件,所以从对话框中选择哪个选项并不重要。当打开新的虚拟机时,VMware 会让我们验证虚拟硬件配置,图 9 - 9 展示了 Fedora Core 5 可用的虚拟硬件清单。
除了下载镜像并将其加载到管理控制台外,我们还可以从标准 Linux 发行版的 CD - ROM 安装 Linux 操作系统。
2. 虚拟化技术的思考
许多分析师选择观望 Linux 虚拟化技术是否会流行起来。作为系统管理员,我们需要权衡掌握这项技术的风险和回报。虚拟化技术虽不像 IBM 推出个人电脑或微软引入分布式文件系统那样影响深远,其管理程序技术的影响力也无法与 SAP、PeopleSoft 或 Oracle Financials 等 ERP 程序相提并论,但像 Xen 和 VMware 这样的技术具有不可否认的好处。
虚拟化通过整合系统资源,提高了服务器的利用率,减少了硬件的过度配置。在虚拟环境中运行现有软件,不仅能保护我们在软件上的投资,还能更好地利用低成本、行业标准的服务器。
3. Linux 脚本编写基础
作为 Linux 系统管理员,我们常用的两个工具是文本编辑器和 shell。当我们厌倦了重复输入命令时,就会想到结合文本编辑器和 shell 创建 shell 脚本来节省精力并减少错误。
Linux 系统本身在很多地方都使用 shell 脚本,特别是在服务和进程管理等可定制任务中。了解这些系统脚本的编写方式,有助于我们解读它们的执行步骤并根据自身需求进行调整。
shell 是从 Linux 的“曾祖父”Unix 继承的众多创新之一。1978 年,贝尔实验室的研究员 Stephen Bourne 为第 7 版 Unix 开发了 Bourne Shell,简称为 sh。后来,在此基础上发展出了 Korn shell(ksh)、C shell(csh),最终出现了现在 GNU/Linux 系统上的标准 Bash shell(bash),它是 Bourne - Again Shell 的缩写,并且仍然支持为原始 Bourne shell 编写的脚本。
3.1 Bash 脚本基础
许多早期操作系统都提供了命令行界面,并允许将命令存储在文本文件中作为批处理作业运行。Unix 的 shell 在灵活性方面有了巨大飞跃,使其成为一种真正的编程语言。
以下是一个交互式示例,展示了 shell 提示符、命令及输出:
admin@server1:~$ date
Thu Aug 24 09:16:56 CDT 2006
shell 脚本的内容通常如下所示:
#!/bin/bash
contents of script...
在 Linux 脚本中,第一行很特殊。如果以
#!
开头,后面的内容就是用于处理脚本其余部分的命令的文件名。如果
#
后面没有跟
!
,则被解释为注释,直到行尾。
我们可以使用喜欢的文本编辑器创建一个名为
hello
的文件,内容如下:
#!/bin/bash
echo hello world
echo bonjour monde
这个文件目前还不能运行,下面我们将介绍如何运行它以及一些基本的语法规则。
Bash 会逐行解释这个脚本,它期望每个命令在单独的一行,但如果行尾以反斜杠
\
结尾,Bash 会将下一行视为当前行的延续,例如:
#!/bin/bash
echo \
hello\
world
这样可以使复杂的行更易读。shell 会忽略空白行和注释行。当 Bash 读取脚本的第二行
echo hello world
时,会将
echo
视为要运行的命令,
hello world
视为其参数,
echo
命令会将参数复制到输出。
要查看
hello
文件的内容,可以使用
cat
命令:
admin@server1:~$ cat hello
#!/bin/bash
echo hello world
echo bonjour monde
3.2 路径名和权限
我们可以通过
bash
命令并带上
hello
参数来执行
hello
文件:
admin@server1:~$ bash hello
hello world
bonjour monde
但如果直接运行
hello
,会出现找不到命令的错误:
admin@server1:~$ hello
bash: hello: command not found
这是因为当我们指定一个命令时,Linux 会在一个名为
path
的目录列表中搜索该文件名的文件,并运行找到的第一个文件。在这种情况下,
hello
不在这些目录中。我们可以使用绝对路径(如
/home/admin/hello
)或相对路径(如
./hello
表示当前目录下的
hello
文件)来运行它。
在运行之前,我们还需要处理文件权限问题。查看
hello
文件的权限:
admin@server1:~$ ls -l hello
-rw-r--r-- 1 admin admin 48 2006-07-25 13:25 hello
这里的权限信息表明,文件所有者(admin)可以读取(r)和写入(w)该文件,组内其他成员和其他用户只能读取(r),没有人可以执行该文件。
尝试使用相对路径运行
hello
会失败:
admin@server1:~$ ./hello
bash: ./hello: Permission denied
我们可以使用
chmod
命令更改权限,有两种方式:
- 使用八进制数字:
admin@server1:~$ chmod 750 hello
admin@server1:~$ ls -l hello
-rwxr-x--- 1 admin admin 50 2006-08-03 15:44 hello
这里,
7
表示文件所有者有读、写、执行权限(4 + 2 + 1),
5
表示组内成员有读、执行权限(4 + 1),
0
表示其他用户没有权限。
- 使用字母:
admin@server1:~$ chmod u=rwx,g=rx hello
admin@server1:~$ ls -l hello
-rwxr-x--- 1 admin admin 50 2006-08-03 15:44 hello
如果要快速为自己、组内成员和其他用户添加读和执行权限,可以使用:
admin@server1:~$ chmod +xr hello
admin@server1:~$ ls -l hello
-rwxr-xr-x 1 admin admin 50 2006-08-03 15:44 hello
现在就可以从命令行运行脚本了:
admin@server1:~$ ./hello
hello world
bonjour monde
3.3 默认路径
Bash 搜索命令的目录列表存储在一个名为
PATH
的 shell 环境变量中。查看
PATH
的内容:
admin@server1:~$ echo $PATH
/bin:/usr/bin
Linux 中
.
表示当前目录,
..
表示当前目录的父目录。如果希望 Linux 总是能在当前目录找到像
hello
这样的命令,可以将当前目录添加到
PATH
:
admin@server1:~$ PATH=$PATH:.
要使这样的更改永久生效,可以在用户主目录下的
.bashrc
文件中添加相应语句,或者由系统管理员在系统范围的启动文件(通常位于
/etc
目录)中添加。
另一种方法是将
hello
脚本移动到
PATH
中已有的目录,但这些目录通常受保护,只有 root 用户可以在其中放置文件。
对于比
hello
更复杂的脚本,这两种方法都有安全隐患。如果
.
在
PATH
中,可能会执行到其他用户在不同目录下同名的脚本。
常见的做法是将自己的脚本放在
/usr/local/bin
或私人的
~/bin
目录中,并在
.bashrc
文件末尾添加以下行将该目录永久添加到
PATH
:
export PATH=$PATH:/usr/local/bin
3.4 I/O 重定向
I/O 重定向和管道是 Unix 的创新,被很多系统借鉴。shell 让我们可以很直观地使用这些功能。
当在控制台或文本窗口输入命令时,手指提供命令的标准输入,眼睛读取命令的标准输出和标准错误输出。我们可以用文件代替手指提供输入或代替眼睛捕获输出。
例如,将
ls
命令的标准输出正常显示在屏幕上,然后重定向到文件:
admin@server1:~$ ls
hello
admin@server1:~$ ls > files.txt
重定向过程是静默的,如果出现错误,错误信息会显示在屏幕上而不是文件中。
admin@server1:~$ ls ciao > files.txt
ls: ciao: No such file or directory
如果
files.txt
在运行命令前已存在,会被覆盖。如果要追加内容,可以使用
>>
:
admin@server1:~$ ls -l >> files.txt
也可以重定向标准错误,例如同时重定向标准输出和标准错误:
admin@server1:~$ ls -l > files.txt 2> errors.txt
这里
2>
是标准错误重定向的符号。如果要将标准输出和标准错误重定向到同一个文件,可以使用:
admin@server1:~$ ls -l > files.txt 2>&1
或者使用快捷方式:
admin@server1:~$ ls -l >& files.txt
如果要追加而不是覆盖,使用
>>
代替
>
。
标准输入也可以重定向,例如搜索包含字符串
foo
的文件名:
admin@server1:~$ ls -l > files.txt
admin@server1:~$ grep foo < files.txt
admin@server1:~$ rm files.txt
我们可以使用管道将这三个步骤合并,避免使用临时文件:
admin@server1:~$ ls -l | grep foo
还可以链式使用管道:
admin@server1:~$ ls -l | grep foo | wc -l
这个命令会统计当前目录下所有文件中字符串
foo
出现的次数。
3.5 变量
Bash 是一种编程语言,变量是其基本特性之一。Bash 变量默认是字符串,除非使用
declare
语句指定其他类型。与很多其他语言不同,我们在使用 Bash 变量前不需要声明或定义。
变量名是一个以字母开头,包含字母、数字或下划线
_
的字符串。通过在变量名前加
$
可以获取变量的值。
以下是一个为变量
hw
赋值并打印的 shell 脚本:
#!/bin/bash
hw="hello world"
echo $hw
由于 Bash 和其他 shell 将空白字符(空格和制表符)视为命令参数分隔符,为了保留空格,需要用双引号
"
或单引号
'
包围字符串。双引号内的 shell 变量会被展开,单引号内则会被视为字面量。
#!/bin/bash
hw="hello world"
echo "$hw"
echo '$hw'
运行这个脚本:
admin@server1:~$ ./hello2
hello world
$hw
我们可以使用
$(command)
或
command
语法将命令的标准输出赋值给变量:
#!/bin/bash
dt=$(date)
dttoo=`date`
echo "Today is $dt"
echo "And so is $dttoo"
特殊变量可以表示命令行参数,
$n
表示第
n
个命令行参数(从 1 开始),
$0
是脚本本身的名称,
$*
包含所有参数作为一个字符串值。
#!/bin/bash
ls -Alv $*
运行脚本:
admin@server1:~$ ./files hello hello2 today
-rwxr-xr-x 1 admin admin 48 2006-07-25 13:25 hello
-rwxr-xr-x 1 admin admin 51 2006-07-25 14:45 hello2
-rwxr-xr-x 1 admin admin 45 2006-07-25 14:49 today
特殊变量
$$
包含当前进程的进程 ID,可以用于创建唯一的临时文件名。
$?
包含最近执行命令的返回状态,可用于检查脚本中程序执行的成功或失败。
3.6 Bash 脚本的有用元素 - 表达式
Bash 表达式包含变量和运算符,如
==
(等于)和
>
(大于),通常用于测试,有几种指定方式:
test $file == "test"
[ $file == "test" ]
[[ $file == "test" ]]
如果使用
test
命令,要注意一些符号有多种含义,需要用引号括起来。使用单或双方括号语法则无需担心引号问题。双方括号功能比单方括号更多,使用表达式时最好用双方括号。
Bash 还有一些有用的特殊内置运算符:
| 运算符 | 说明 |
| ---- | ---- |
|
-a file
| 如果文件存在则为真 |
|
-d file
| 如果文件存在且为目录则为真 |
|
-f file
| 如果文件存在且为普通文件则为真 |
|
-r file
| 如果文件存在且可读则为真 |
|
-w file
| 如果文件存在且可写则为真 |
|
-x file
| 如果文件存在且可执行则为真 |
通过以上内容,我们了解了 VMware 客操作系统的安装方法、虚拟化技术的特点以及 Bash 脚本编写的基础知识,包括脚本的创建、运行、权限设置、路径管理、I/O 重定向、变量使用和表达式等,这些知识将帮助我们更好地管理 Linux 系统和编写高效的脚本。
4. 循环结构
在编写 Bash 脚本时,循环结构是非常实用的,它可以帮助我们重复执行一系列命令。Bash 主要提供了
for
、
while
和
until
三种循环结构。
4.1 for 循环
for
循环用于遍历一个列表中的元素,并对每个元素执行相同的操作。基本语法如下:
for variable in list
do
commands
done
例如,遍历一个数字列表并打印每个数字:
#!/bin/bash
for num in 1 2 3 4 5
do
echo $num
done
运行这个脚本,会依次输出 1 到 5。
我们也可以使用
seq
命令生成一个数字序列:
#!/bin/bash
for num in $(seq 1 5)
do
echo $num
done
效果与上面的脚本相同。
4.2 while 循环
while
循环会在条件为真时不断执行循环体中的命令。基本语法如下:
while condition
do
commands
done
例如,使用
while
循环打印 1 到 5 的数字:
#!/bin/bash
num=1
while [ $num -le 5 ]
do
echo $num
num=$((num + 1))
done
在这个脚本中,首先将
num
初始化为 1,然后在每次循环中检查
num
是否小于等于 5,如果是则打印
num
并将其加 1,直到
num
大于 5 时退出循环。
4.3 until 循环
until
循环与
while
循环相反,它会在条件为假时不断执行循环体中的命令,直到条件为真时退出循环。基本语法如下:
until condition
do
commands
done
例如,使用
until
循环打印 1 到 5 的数字:
#!/bin/bash
num=1
until [ $num -gt 5 ]
do
echo $num
num=$((num + 1))
done
在这个脚本中,首先将
num
初始化为 1,然后在每次循环中检查
num
是否大于 5,如果不是则打印
num
并将其加 1,直到
num
大于 5 时退出循环。
5. 函数
在 Bash 脚本中,函数可以将一组相关的命令封装起来,方便重复使用。函数的定义和调用方式如下:
5.1 函数定义
function_name() {
commands
}
或者
function function_name {
commands
}
例如,定义一个简单的函数来打印问候语:
#!/bin/bash
greet() {
echo "Hello, $1!"
}
greet "John"
在这个脚本中,定义了一个名为
greet
的函数,它接受一个参数并打印问候语。然后调用这个函数并传入参数 “John”。
5.2 函数返回值
Bash 函数可以通过
return
语句返回一个退出状态码,范围是 0 到 255。返回状态码可以用于判断函数的执行结果。
#!/bin/bash
add_numbers() {
result=$(( $1 + $2 ))
return $result
}
add_numbers 3 5
echo $?
在这个脚本中,定义了一个名为
add_numbers
的函数,它接受两个参数并将它们相加,然后通过
return
语句返回相加的结果。在调用函数后,使用
$?
来获取函数的返回状态码。
6. 脚本调试
在编写 Bash 脚本时,调试是一个重要的环节。以下是一些常用的调试方法:
6.1 使用
set -x
在脚本中添加
set -x
可以开启调试模式,它会在执行每条命令之前打印出命令及其参数。
#!/bin/bash
set -x
num=5
result=$((num * 2))
echo $result
set +x
在这个脚本中,
set -x
开启调试模式,
set +x
关闭调试模式。
6.2 使用
bash -x
在运行脚本时,可以使用
bash -x
选项来开启调试模式。
bash -x script.sh
这样会在执行脚本的每条命令之前打印出命令及其参数。
7. 不同脚本语言的比较
除了 Bash 脚本,还有其他一些常用的脚本语言,如 Perl、PHP 和 Python。以下是一个简单的应用,用这几种语言分别实现,以便比较它们的风格、语法、易用性和适用领域。
7.1 Bash 实现
#!/bin/bash
for i in $(seq 1 10)
do
if [ $((i % 2)) -eq 0 ]
then
echo "$i is even"
else
echo "$i is odd"
fi
done
7.2 Perl 实现
#!/usr/bin/perl
for ($i = 1; $i <= 10; $i++) {
if ($i % 2 == 0) {
print "$i is even\n";
} else {
print "$i is odd\n";
}
}
7.3 PHP 实现
#!/usr/bin/php
<?php
for ($i = 1; $i <= 10; $i++) {
if ($i % 2 == 0) {
echo "$i is even\n";
} else {
echo "$i is odd\n";
}
}
?>
7.4 Python 实现
#!/usr/bin/python
for i in range(1, 11):
if i % 2 == 0:
print(f"{i} is even")
else:
print(f"{i} is odd")
通过比较可以发现,Bash 脚本适合处理系统管理任务和简单的文本处理;Perl 在文本处理和正则表达式方面表现出色;PHP 常用于 Web 开发;Python 则具有简洁的语法和丰富的库,适用于各种领域。
8. 总结
本文详细介绍了 Linux 系统中 VMware 客操作系统的安装方法,以及 Bash 脚本编写的多个方面,包括基础语法、路径和权限管理、I/O 重定向、变量使用、表达式、循环结构、函数、脚本调试等。同时,还对 Bash 与 Perl、PHP、Python 等脚本语言进行了简单比较。
以下是本文内容的总结流程图:
graph LR
A[VMware 安装] --> B[Fedora Core 5 安装步骤]
C[Bash 脚本编写] --> D[基础语法]
C --> E[路径和权限管理]
C --> F[I/O 重定向]
C --> G[变量使用]
C --> H[表达式]
C --> I[循环结构]
C --> J[函数]
C --> K[脚本调试]
L[脚本语言比较] --> M[Bash]
L --> N[Perl]
L --> O[PHP]
L --> P[Python]
掌握这些知识,我们可以更好地管理 Linux 系统,提高工作效率,根据不同的需求选择合适的脚本语言来解决问题。希望本文能为你在 Linux 系统管理和脚本编写方面提供有价值的参考。
超级会员免费看
42

被折叠的 条评论
为什么被折叠?



