组合键可以在各种输入法之间 进行切换。
前往红联论坛参与此主题的讨论 如果有疑问,请前往这里提交你的问题,我们将尽力帮你解决
红联论坛
__________________
希望能和你相互交流,愿意和您分享学习、进步中的每分喜悦与快乐
---------------------------------------------
http://tzhsuccess.itpub.net
向版主反映这个帖子 查看tzhsuccess 的IP地址
143楼 旧帖 06-07-17 23:38
[ 大 中 小 ] 给予该贴好评 编辑/删除 引用/回复
tzhsuccess
高级会员
注册日期: 2004 Apr
来自: 太?系-?子座
技术贴数:7934
论坛积分:31670
论坛排名:67
论坛徽章:23
会员2006贡献徽章 行业板块每日发贴之星 ERP板块每日发贴之星
Shell启动文件与环境变量
每个shell的起动动动,执行命令和程序的机制,如何处理命令和程序的输入输出,以及任何编程都受到某些环境变量设置的影响.每个系统都有一个初始的系统启动文件,通常是/etc/profile.这个文件包含了对shell和其他一些实用程序起作用的重要环境变量的初始设置.另外特定的shell还有一些隐藏的文件和点文件在你启动该shell的时候执行,这些文件也叫shell的启动文件,通常是一用户的主目录下的~/.profile,或者是一个特定shell的profile或login文件.例如bash的profile汉?ogin文件通常是~/.bash_profile与~/.bash_login.
当你登录并且登录shell是bash时,bash首先执行/etc/profile文件中的命令(如果该文件存在),然后它顺序寻找~/.bash_profile,~/.bash_logi或~/.profile文件,并执行找到的第一个可读文件中的命令.当登录bash退出时,它将执行~/.bash_logout文件中的命令.
当启动一个交互的bash时,它将执行~/.bashrc文件中的命令(如果该文件存在并且可读).当非交互地启动以运行一个shell脚本时,bash将查找bash_env环境 变亮康哪谌??确定执行文件的名称.
如果你使用的是TC shell,它将执行/etc/csh.cshrc或 etc/.chsrc文件中的命令(如果该文件存在并且可读).登录shell然后将执行/etc/csh.login文件中的命亮??如果该文件存在并且可读).每一?hell(登录shell或非登录 shell)然后将执行~/.tcshrc文件(假如~/.tcshrc不存在就是 ~/.cshrc文件)中的命令,并读取~/.history文件的内容.登录shell将执行~/.login和 ~/.cshdirs文件中的命令.当一个TC shell退出时,它将执行/etc/csh.logout和 ~/.login文件中的命令(如果该文件存在并且可读).
前往红联论坛参与此主题的讨论 如果有疑问,请前往这里提交你的问题,我们将尽力帮你解决
红联论坛
__________________
希望能和你相互交流,愿意和您分享学习、进步中的每分喜悦与快乐
---------------------------------------------
http://tzhsuccess.itpub.net
向版主反映这个帖子 查看tzhsuccess 的IP地址
144楼 旧帖 06-07-17 23:38
[ 大 中 小 ] 给予该贴好评 编辑/删除 引用/回复
tzhsuccess
高级会员
注册日期: 2004 Apr
来自: 太?系-?子座
技术贴数:7934
论坛积分:31670
论坛排名:67
论坛徽章:23
会员2006贡献徽章 行业板块每日发贴之星 ERP板块每日发贴之星
shell提示行魔术
如果您很容易使 shell 提示行变得色彩绚烂斓且带有更多信息,为什么还要坚持用单调的标准 shell 提示行呢?在这篇技巧中,Daniel Robbins 将说明如何获得符合您的意愿的 shell 提示行,并会说明如何动态更新 X 终端的标题栏。
作为 Linux/UNIX 人,我们有很长的时间是在 shell 中工作,并且在许多情况下,下面这一行就是始终盯着我们的那个提示行:
bash-2.04$
如果您恰巧是超级用户 (root),您就有权使用下面这个美丽的标示“身份”的提示行版本:
bash-2.04#
这些提示行并不是十分漂亮。这也就难怪几种 Linux 版本对默认提示行进行了升级,在其中增加了颜色和更多的信息。但是,即便您恰好有一个本身带有很好的彩色提示行的新式版本,它也不可能是完美无缺的。您或许希望在提示行中增加或更改几种颜色,或者增加(或删除)一些信息。从头开始设计属于您自己的彩色的、经过装饰的提示行并不难。
提示行基础
在 bash 下,可以通过更改 PS1 环境变量的值来设置提示行,如下所示:
$ export PS1="> "
>
更改会立即生效,通过将 "export" 定义放在您的 ~/.bashrc 文件中可将这种更改固定下来。只要您愿意,PS1 可以包含任意数量的纯文本:
$ export PS1="This is my super prompt > "
This is my super prompt >
尽管这很有趣,但在提示行中包含大量静态文本并不是特别有用。大多数定制的提示行包含诸如用户名、工作目录或主机名之类的信息。这些花絮信息可以帮助您在 shell 世界中遨游。例如,下面的提示行将显示您的用户名和主机名:
$ export PS1="u@H > "
drobbins@freebox >
这个提示行对于那些以多个不同名称的帐户登录多台机器的人尤为有用,因为它可以提醒您:您目前在哪台机器上操作,拥有什么权限。
在上面的示例中,我们使用了专用的用反斜杠转义的字符序列,藉此通知 bash 将用户名和主机名插入提示行中,当这些转义字符序列出现在 PS1 变量中时,bash 就会用特定的值替换它们。我们使用了序列 "u"(表示用户名)和 "H"(表示主机名的第一部分)。下面是 bash 可识别的全部专用序列的完整列表(您可以在 bash man page 的 "PROMPTING" 部分找到这个列表):
序列 说明
a ASCII 响铃字符(也可以键入 07)
d "Wed Sep 06" 格式的日期
e ASCII 转义字符(也可以键入 33)
h 主机名的第一部分(如 "mybox")
H 主机的全称(如 "mybox.mydomain.com")
j 在此 shell 中通过按 ^Z 挂起的进程数
l 此 shell 的终端设备名(如 "ttyp4")
n 换行符
r 回车符
s shell 的名称(如 "bash")
t 24 小时制时间(如 "23:01:01")
T 12 小时制时间(如 "11:01:01")
@ 带有 am/pm 的 12 小时制时间
u 用户名
v bash 的版本(如 2.04)
V Bash 版本(包括补丁级别) ?/td>
w 当前工作目录(如 "/home/drobbins")
W 当前工作目录的“基名 (basename)”(如 "drobbins")
! 当前命令在历史缓冲区中的位置
# 命令编号(只要您键入内容,它就会在每次提示时累加)
$ 如果您不是超级用户 (root),则插入一个 "$";如果您是超级用户,则显示一个 "#"
xxx 插入一个用三位数 xxx(用零代替未使用的数字,如 "07")表示的 ASCII 字符
反斜杠
[ 这个序列应该出现在不移动光标的字符序列(如颜色转义序列)之前。它使 bash 能够正确计算自动换行。
] 这个序列应该出现在非打印字符序列之后。
这样,您已经知道了 bash 中用反斜杠转义的全部专用序列。请稍微演练一下这些序列,以对它们的工作方式获得一些感性认识。在您做了一些测试之后,下面开始添加颜色。
彩色化
添加颜色相当容易;第一步是设计不带颜色的提示行。然后,我们所要做的只是添加终端(而不是 bash)可识别的专用转义序列,以使它以彩色显示文本的某些部分。标准 Linux 终端和 X 终端允许您设置前景(文字)颜色和背景颜色,如果需要,还可以启用 "bold" 字符。有八种颜色可供我们选择。
颜色是通过在 PS1 中添加专用序列来选择的 -- 基本上是夹在 "e["(转义开方括号)和 "m" 之间数字值。如果指定一个以上的数字代码,则用分号将它们分开。下面是一个颜色代码示例:
"e[0m"
如果将数字代码指定为零,则它就会通知终端将前景、背景和加粗设置重置为它们的默认值。您可能会在在提示行结束时使用这个代码,以使您键入的文字成为非彩色的。现在,让我们看一下这些颜色代码。请注意下面的抓屏结果:
颜色表
要使用这个表,首先请查找您要使用的颜色,然后查找对应的前景编号 (30-37) 和背景编号 (40-47)。例如,如果您喜欢黑底绿字,则可将编号分别设为 32 和 40。然后打开您的提示行定义并在其中添加适当的颜色代码。下面的定义:
export PS1="w> "
变为:
export PS1="e[32;40mw> "
到现在为止,提示行尽管已经很不错了,但仍不太完美。在 bash 显示出工作目录以后,我们需要使用 "e[0m" 序列将颜色重新设置为正常值。
export PS1="e[32;40mw> e[0m"
这个定义将显示一个漂亮的绿色提示行,但我们仍需要做一些扫尾工作。我们不需要包括 "40" 这个背景颜色设置,因为它将背景设置为黑色,而黑色是默认颜色。此外,绿色还很暗;我们通过添加一个 "1" 颜色代码来修正这个问题,这将启用更亮的加粗文字。除了这个修改之外,我们还需要将全部非打印字符用专用的 bash 转义序列 "[" 和 "]" 括起来。这两个序列通知 bash,被括起来的字符不占用行上的任何空间,这样就使自动换行能够继续正常工作。没有这两个转义序列,尽管您有了一个非常漂亮的提示行,但是如果您键入的命令恰好到达终端的最右端,就会造成显示混乱。下面是我们最终的提示行:
export PS1="[e[32;1m]w> [e[0m]"
别担心在同一个提示行中使用几种颜色,就像下面这样:
export PS1="[e[36;1m]u@[e[32;1m]H> [e[0m]"
Xterm 中的乐趣
我已说明了如何在提示行中添加信息和颜色,但您还可以更进一步。您可以通过在提示行中添加专用代码来使 X 终端(如 rxvt 或 aterm)的标题栏得到动态更新。您所要做的只是将下面的序列添加到您的 PS1 提示行中:
"e]2;titlebara"
只须用您希望其出现在 xterm 标题栏中的文字替换子串 "titlebar" 即可,现在已经一切就绪了!不必使用静态文字;您可以将 bash 转义序列插入标题栏中。请查看下面这个示例,它将用户名、主机名和当前工作目录显示在标题栏中,并定义了一个简短、明亮的绿色提示行:
export PS1="[e]2;u@H wae[32;1m]>[e[0m] "
这就是我在上面的抓屏结果中所用的那个提示行。我喜欢这个提示行,因为它将全部信息显示在标题栏上,而不是显示在终端上,终端对一行可以显示多少字符有限制。顺便提一句,确保用 "[" 和 "]" 将您的标题栏序列括起来(因为就终端而言,这个序列是非打印序列)。将大量信息放在标题栏中的问题是,如果您使用非图形终端(如系统控制台),则看不到这些信息。为了解决这个问题,可以在您的 .bashrc 中添加以下几行:
if [ "$TERM" = "linux" ]
then
#we're on the system console or maybe telnetting in
export PS1="[e[32;1m]u@H > [e[0m]"
else
#we're not on the console, assume an xterm
export PS1="[e]2;u@H wae[32;1m]>[e[0m] "
fi
这个 bash 条件语句将根据当前的终端设置动态设置提示行。为了获得一致性,您一定希望配置您的 ~/.bash_profile,以便它在启动时搜索 (source) 您的 ~/.bashrc。确保您的 ~/.bash_profile 文件中有以下这样一行:
source ~/.bashrc
这样,无论您开启一个登录 shell 还是一个非登录 shell,都会获得同样的提示行。
好了,您已掌握了提示行魔术。现在尽情享受一下,制作一个漂亮的彩色提示行吧
前往红联论坛参与此主题的讨论 如果有疑问,请前往这里提交你的问题,我们将尽力帮你解决
红联论坛
__________________
希望能和你相互交流,愿意和您分享学习、进步中的每分喜悦与快乐
---------------------------------------------
http://tzhsuccess.itpub.net
向版主反映这个帖子 查看tzhsuccess 的IP地址
145楼 旧帖 06-07-17 23:39
[ 大 中 小 ] 给予该贴好评 编辑/删除 引用/回复
tzhsuccess
高级会员
注册日期: 2004 Apr
来自: 太?系-?子座
技术贴数:7934
论坛积分:31670
论坛排名:67
论坛徽章:23
会员2006贡献徽章 行业板块每日发贴之星 ERP板块每日发贴之星
Sobell谈bash和Linux命令行命运
《Linux命令、编辑器和外壳编程实践指南》一书的作者Mark G. Sobell在接受LinuxPlanet栏目采访时谈了他本人对Linux命令行命运的看法。
LinuxPlanet(以下简称LP):命令行死亡了吗?
答:不,根本就没有死亡。对于某些人和执行某些任务来说,使用图形界面更容易和更简洁。这实际上依赖于你要做什么和你是谁。图形用户界面和命令行之间的区别就像自动变档与变速杆一样。我使用变速杆是因为它能够让我更好地控制汽车,让我更多地感觉到汽车在做什么以及汽车是如何做到的。
当然,这个讨论假设你是以系统管理员的级别操作文件的。有些应用程序有用户图形界面,有些应用程序也许没有这种界面,或者只有非常原始的命令行界面。设法从命令行运行这些应用程序是没有意义的。
对命令行有好处的一件事情是它能够让你访问数百个工具软件。在命令行上面,你可以使用一个管道把工具软件结合在一起执行一项单个工具软件无法完成的工作。下面是从我的“Linux命令、编辑器和外壳编程实践指南”一书中摘录的部分内容,谈了有关这些管道及其连接的过程:
“一个过程是Linux执行一个命令。过程之间的通信是UNIX/Linux的验证证明之一。一个通道(书写为垂直的直线“|”,在命令行中或者键盘上是一个垂直的实线)提供了这种通信最简单的方式。简单地说,一个通道接受一个工具软件的输出,然后把那个输出输入到其它工具软件。使用UNIX/Linux的词汇,这个通道接受了一个过程的标准输出,并把这个标准的输出作为另一个过程的标准输入。一个过程在屏幕上显示的大多数内容将发送给标准的输出。如果你没有重新定向这个输出,这个输出就在屏幕上显示出来。使用一个通道,你可以重新定向这个输出,这样它就变成了另一个工具软件的标准的输入。”
例如,你可以把列出目录中文件的命令“ls”与计算一个目录中的文件和字数的命令“wc -w”结合在一起使用:
$ ls | wc -w
45
在Linux系统管理领域,用户图形界面通常是建在命令行工具之外的,因此,你不能得到用户图形界面工具的好处。当然,除非你能使用鼠标。你在命令行下面能够完成的工作在图形用户界面系统管理工具中经常无法完成。
Bourne和Bourne外壳程序
LP:你能讨论一下bash(Bourne Again Shell)并且解释一下它与原来的Bourne外壳程序有什么区别吗?
答:这个外壳程序(shell)是命令行的解释程序,它分析你输入的命令行并且调用你申请的程序,并且把你在命令行中输入的参数传递给这个程序。这个外壳程序也是一种高级的编程语言。bash是许多Linux系统默认的外壳程序。大多数Linux发布版软件还包含其它的外壳程序,甚至还有更多的外壳程序可供下载。
由GNU计划编写的bash包含了原始版本的Bourne外壳程序,那是AT&T公司发布的UNIX下面的第一个外壳程序。我曾经建议读者考虑使用C外壳程序作为他们的交互式外壳程序,因为它拥有原始版本的Bourne外壳程序所没有的一些重要功能。目前,bash拥有所有这些功能,而且某些bash还包括命令完成、历史(这样你可以编辑和重复以前的命令)和工作控制(允许你在前端和后端之间转移工作)等功能。当然,你可以使用bash编写外壳程序脚本(批处理文件)。
许多Linux系统外壳程序脚本是从“#!/bin/sh”开始的。这一行命令让脚本在外壳程序下运行。这个外壳程序不是Bourne外壳程序的一部分,而是一个指向bash的链接。
由于具有长期的和成功的历史,原始的Bourne外壳程序一直用来编写许多帮助管理Unix系统的外壳脚本。其中有些在Linux中出现的脚本称作bash脚本。虽然bash脚本包含了许多原始的Bourne外壳程序中所没有的扩展功能和特性,但是,bash保持了对原始的Bourne外壳程序的兼容,因此你可以在bash下面运行Bourne外壳脚本。原始的Bourne外壳程序在Unix系统中称作sh。在Linux系统中,sh是指向bash的一个符号链接,以确保需要Bourne外壳程序的脚本能够运行。当被称作sh的时候,bash尽最大的努力效仿原始的Bourne外壳程序。
LP:你会建议Linux的新手学习bash还是学习TC外壳程序?
答:如果你是一个顽固的C语言外壳程序员,你可以继续使用TC外壳程序(tcsh)。否则,我建议你使用bash。几乎所有的控制Linux的管理外壳脚本程序都是由bash运行的。因此,如果你学习bash,你将能够很容易地理解和修改这些脚本。
awk
LP:你为什么使用awk?
答:这是一个很好的问题,特别是在很多人直接使用Perl语言的时候。这个工具软件简单而功能强大。在Perl出现之前,awk一直是操作文件的工具之一。目前,awk仍是有用的。GNU版本的awk称作gawk,有一些新的功能,使其成为一个非常有用的工具。下面是我的书中讨论的有关如何让gawk与协作进程之间相互通信的部分内容:
协作进程:双向I/O
协作进程是与另一个进程并行运行的一个进程。从3.1版本开始,gawk能够启动一个协作进程直接与后台进程交换信息。当你在客户机/服务器环境中工作,设置一个SQL前端和后端或者在一个网络上与一个远程系统交换数据的时候,协作进程是很有用的。gawk句法通过在启动后台进程的程序名称前面添加一个运算符号“|&”来识别一个协助进程。
一个协助进程指令必须是一个过滤器(也就是说,它读取标准的输入并且写入标准的输出),必须在完成一行输出之后就进行刷新,而不是积累很多行很以后再进行输出。当一个指令作为协作进程被启动之后,它将通过一个双向的通道与一个gawk程序连接,这样,你就可以对这个协作进程进行读写操作。
当与tr工具一起使用时,这个工具在完成每一行指令之后不刷新其输出。这个“to_upper”外壳脚本是不刷新其输出的tr指令的外壳。这个过滤器可以作为协作进程运行。对于读取的每一行指令,“to_upper”写入这些行,并且把这些行翻译成大写字母和标准的输出。如果你要“to_upper”显示调试的输出,可删除“set -x”前面的“#”。
$ cat to_upper
#!/bin/bash
#set -x
while read arg
do
echo "$arg" | tr '[a-z]' '[A-Z]'
done
$ echo abcdef | to_upper
ABCDEF
g6程序启动“to_upper”作为一个协作进程。这个gawk程序读取标准的输入或者在命令行中指定的一个文件,把这个输入翻译成大写字母,并把翻译的数据写入一个标准的输出。
$ cat g6
{
print $0 |& "to_upper"
"to_upper" |& getline hold
print hold
}
$ gawk -f g6 < alpha
AAAAAAAAA
BBBBBBBBB
CCCCCCCCC
DDDDDDDDD
这个g6程序在括号之内有一个混合的指令,包含三个指令。由于没有执行方式,gawk对于每一行输入内容都执行一次这个混合的指令。
第一个指令“print $0”把当前的记录发送到标准的输出。“|&”运算符把标准的输出从新指向名为“to_upper”的程序。“to_upper”作为一个协作进程在运行。这些程序的外边需要一个括号。第二个指令把来自“to_upper”的标准输出重新指向一个“getline”指令。这个指令将其标准的输出复制到这个名为“hold”的变量。第三个指令“print hold”把“hold”变量的这个内容发送到标准的输出。
这个工具的名称是“tr”
LP:你能不能更多地谈一下“tr”工具?
答:哦,tr,好的。首先想到的事情是这是一个微不足道的问题的答案。命名一个Linux工具。这个工具仅接收来自标准输入的输入,从来不接收作为来自命令行变量的文件的输入。这个怪物只是有时候有用,但是,当它有用的时候,它是非常有用的。下面是摘录一些有关“tr”的内容:
tr工具读取标准输入中每一个输入的字符,把字符镜像为一个替代的字符并删除原来的字符或者把不再管那个字符。这个工具读取标准的输入并且写入标准的输出。
tr工具一般与两个参数一起使用,string1(字符串1)和string2(字符串2)。每个字符在这两个字符串中的位置是非常重要的:每一次tr发现在其输入的string1中的一个字符的时候,它都要用string2中相对应的字符取代那个字符。
使用一个参数,string1和“--delete”(删除指令)的选项,tr删除在string1中指定的字符。这个“squeeze-repeats ”(缩减连续重复的字符)选项使用一个出现的字符取代在string1中连续出现的字符,例如abbc将变成abc。
你可以使用一个连字符代表在instring1或者string2中的一系列字符。这两个命令行在下面的例子中产生同样的结果:
$ echo abcdef | tr 'abcdef' 'xyzabc'
xyzabc
$ echo abcdef | tr 'a-f' 'x-za-c'
xyzabc
下面这个例子演示了隐藏文本的流行的做法。这个方法通常称作“ROT13”(rotate 13),因为它用第十三个字母代替第一个字母,用第十四个字母代替第二个字母,以此类推。
$ echo The punchline of the joke is ... |
> tr 'A-M N-Z a-m n-z' 'N-Z A-M n-z a-m'
Gur chapuyvar bs gur wbxr vf ...
为了使这个文本再次智能化,把给tr的参数顺序倒过来:
$ echo Gur chapuyvar bs gur wbxr vf ... |
> tr 'N-Z A-M n-z a-m' 'A-M N-Z a-m n-z'
The punchline of the joke is ...
这个“--delete”选项使tr删除选择的字符:
$ echo If you can read this, you can spot the missing vowels! |
> tr --delete 'aeiou'
If y cn rd ths, y cn spt th mssng vwls!
在下面的例子中,tr替换几个字符并且产生与单个字符相同的一对儿字符:$ echo tennessee | tr --squeeze-repeats 'tnse' 'srne'
serene
下一个例子用一个“新文件”字符替换在draft1文件中的没有按照字母顺序排列的每一个字符。输出是一个词汇列表,每一行一个单词:
$ tr --complement --squeeze-repeats '[:alpha:]' '\n' < draft1
最后一个例子是使用字符类提升那里的字符串“hi there”:
$ echo hi there | tr '[:lower:]' '[:upper:]'
HI THERE
总结
LP:最后还有什么想法吗?
答:我想说命令行并不适用于每一个人。命令行适用于那些要求亲手操作和对他们驯服的野兽有更强的控制力的那些用户。学习外壳程序能够做什么已经成功了一半。成功的另一半是学习一些与Linux发布版一起推出的许多工具的知识。你不需要了解每一个指令的每一个参数。了解每一个指令名称的含义和每个指令基本上能做什么就足够了。你可以阅读我的书中有关人和信息的内容或者有关指令参考的部分。查看tac工具并且在一开始的时候会对这个工具名称的起源感到可笑。
前往红联论坛参与此主题的讨论 如果有疑问,请前往这里提交你的问题,我们将尽力帮你解决
红联论坛
__________________
希望能和你相互交流,愿意和您分享学习、进步中的每分喜悦与快乐
---------------------------------------------
http://tzhsuccess.itpub.net
向版主反映这个帖子 查看tzhsuccess 的IP地址
146楼 旧帖 06-07-17 23:39
[ 大 中 小 ] 给予该贴好评 编辑/删除 引用/回复
tzhsuccess
高级会员
注册日期: 2004 Apr
来自: 太?系-?子座
技术贴数:7934
论坛积分:31670
论坛排名:67
论坛徽章:23
会员2006贡献徽章 行业板块每日发贴之星 ERP板块每日发贴之星
从零开始:Linux基础教程之命令的使用
对于 Linux 新手,或者那些想要重新审视或改进自己对基本 Linux 概念(比如:复制和移动文件、创建符号和硬链接、设置文件系统对象所有权和权限以及同管道和重定向一起使用 Linux 的标准文本处理命令)的理解的人来说,本系列连载文章之一是理想的教材。沿着这个方向,我们将一起分享很多心得、技巧和窍门,使该教程甚至对于那些具有丰富经验的 Linux 老手来说都是“有血有肉”,并且是实用的。
对于初学者而言,本系列文章的许多内容都很新颖,而更有经验的 Linux 用户可能会发现本教程是使他们基本的 Linux 技能“炉火纯青”的有效途径。
介绍 bash
shell
如果您使用过 Linux 系统,那么您知道当登录时,将会看到像这样的提示符:
$
您所看到的特殊的提示符可能看起来很不一样。它可能包含系统的主机名、当前的工作目录名,或者两者都有。但是不管这个特殊的提示符看起来像什么,有一件事是肯定的。打印出这个提示符的程序叫“shell”,极有可能您的特殊的 shell 是一个叫 bash 的程序。
您在运行 bash 吗?
您可以通过输入下面的命令来检查您是否正在运行 bash:
$ echo $SHELL
/bin/bash
如果上面的命令行报错或者不会类似地响应我们的示例,那么您可能正在运行一个不同于 bash 的 shell。
关于 bash
Bash 是“Bourne-again shell”的首字母缩写,它是大多数 Linux 系统缺省的 shell。shell 的任务是执行您的命令,使您能够与 Linux 系统进行交互。当您输完命令,您可以通知 shell 执行 exit 或 logout 命令,在此您将返回到登录提示符。顺便提一下,您还可以通过在 bash 提示符下按 control-D 来注销。
使用“cd”
您可能已经发现,目不转睛地盯着bash提示符可不是世界上最让人感到有劲的事。那么,让我们来开始用 bash 来浏览我们的文件系统。在提示符下,输入下面的命令(不包括 $):
$ cd /
我们只告诉 bash 您想在 /(也称为根目录)中工作;系统上的所有目录形成一棵树,/ 被认为是这棵树的顶部,或者是根。cd设置当前您正在工作的目录,也称为“当前工作目录”。
路径
要看 bash 的当前工作目录,您可以输入:
$ pwd
/
在上面的示例中,cd 的 / 参数叫做路径。它告诉 cd 我们要转到什么地方。特别是,/ 参数是一个绝对路径,意味着它指定了相对于文件系统树的根的位置。绝对路径这里有几个其它的绝对路径:
/dev
/usr
/usr/bin
/usr/local/bin
您可以看到,所有绝对路径有一个共同点就是,它们都以/开头。通过路径/usr/local/bin,我们告诉 cd 进入 / 目录,接着进入这个目录之下的usr目录,然后再进入 local 和 bin。绝对路径总是通过是否以 / 开头来判断。
相对路径
另一种路径叫相对路径。在 Bash 中,cd 以及其它命令总是解释那些相对于当前目录的路径。相对路径绝不会以 / 开头。这样,如果我们在 /usr 中:
$ cd /usr
那么,我们可以使用相对路径来转到 /usr/local/bin 目录:
$ cd local/bin
$ pwd
/usr/local/bin
使用“..”
相对路径还可以包含一个或多个 .. 目录。.. 目录是指向父目录的专门目录。那么,继续前面的示例:
$ pwd
/usr/local/bin
$ cd ..
$ pwd
/usr/local
您可以看到,现在我们的当前目录是 /usr/local。我们能够“后退”到相对于我们所在的当前目录的一个目录。此外,我们还可以将 \\\\\"..\\\\\\" 添加到一个现有的相对路径中,使我们可以进入与我们已在目录并排的目录,例如:
$ pwd
/usr/local
$ cd ../share
$ pwd
/usr/share
相对路径示例
相对路径可以变得相当复杂。这里有几个示例,所有的都没有显示出结果的目标路径。请试着推断一下,输入这些命令后,您最终将会转到什么地方:
$ cd /bin
$ cd ../usr/share/zoneinfo
$ cd /usr/X11R6/bin
$ cd ../lib/X11
$ cd /usr/bin
$ cd ../bin/../bin
现在,试验一次,看看您的推断是否正确。
理解“.”
在我们结束 cd 的介绍之前,我们还需要讨论一些更多的内容。首先,还有另一个叫 . 的专门的目录。它表示“当前目录”。然而该目录不为 cd 命令使用,它通常用来执行一些当前目录中的程序,如下所示:
$ ./myprog
在上面的示例中,驻留在当前工作目录中的 myprog 可执行文件将被执行。
cd 和主目录
如果我们想要转到主目录,我们可以输入:
$ cd
没有参数,cd 将转到主目录,对于超级用户来说是 /root,对于一般用户来说通常是/home/username。但是,如果我们想要指定一个主目录中的文件,将会怎样呢?可能我们想要将一个文件参数传给 myprog 命令。如果该文件在主目录中,我们可以输入:
$ ./myprog /home/drobbins/myfile.txt
但是,使用像这样的绝对路径并不总是很方便。幸好,我们可以使用 ~(代字符)字符来完成同样的事:
$ ./myprog ~/myfile.txt
其他用户的主目录Bash 将把单独的 ~ 扩展为指向主目录,然而您还可以用它来指向其他用户的主目录。例如,如果我们想要引用 fred 的主目录中的名为 fredsfile.txt 的文件,可以输入:
$ ./myprog ~fred/fredsfile.txt
使用 Linux 命令
介绍 ls
现在,我们将快速地看一看 ls 命令。很可能,您已经很熟悉 ls,并且知道只输入 ls 本身将列出当前工作目录的内容: $">[b]通过指定 -a 选项,您可以看到目录中的所有文件,包括隐藏文件 ? 那些以 . 开头的文件。您可以在下面的示例中看到,ls -a 将显示 . 和 .. 专门的目录链接:$">[b]递归和索引节点清单。
您可以使用 -d 来查看目录本身,而您还可以用 -R 来完成相反的工作 ? 不仅只查看一个目录内部,而且要递归地查看该目录内所有的目录内部!我们将不会有对应该选项的任何示例输出(因为它一般占很大的篇幅),但是为了感觉一下它是怎样工作的,您可以试几个 ls -R 和 ls -Rl 命令。最后,ls 的 -i 选项可以用来在清单中显示文件系统对象的索引节点号:
$ ls -i /usr
1409 X11R6 314258 i686-linux
43090 libexec 13394 sbin
1417 bin 1513 i686-pc-linux-gnu
5120 local 13408 share
8316 distfiles 1517 include
776 man 23779 src
43 doc 1386 info 93892 portage
36737 ssl
70744 gentoo-x86 1585 lib 5132
portage.old 784 tmp
理解索引节点,第 1 部分
文件系统的每个对象都分配到一个独一无二的索引,叫做索引节点号。这可能看起来微不足道,但是理解索引节点对于理解许多文件系统操作来说很重要。例如,请考虑出现在每个目录中的 . 和 .. 链接。为了完全理解 .. 目录实际上是什么,我们将先来看一看 /usr/local 的索引节点号:
$ ls -id /usr/local
5120 /usr/local
/usr/local
目录有一个 5120 索引节点号。现在,我们来看一 看 /usr/local/bin/.. 的索引节点号:
$ ls -id /usr/local/bin/..
5120 /usr/local/bin/..
您可以看到,/usr/local/bin/..具有和/usr/local相同的索引节点号!这就是我们抓住的问题的实质。过去,我们认为 /usr/local 是这个目录本身。
现在,我们发现索引节点 5120实际上是这个目录,并且我们发现了指向该索引节点的两个目录条目(叫做“链接”)。/usr/local 和 /usr/local/bin/..都链接到索引节点 5120。虽然索引节点 5120 只在磁盘中的一地方存在,但是多个目录条目都链接到它上面。事实上,通过使用 ls -dl 命令,我们可以看到索引节点 5120 被引用的总次数
$ ls -dl /usr/local
drwxr-xr-x 8 root root 240 Dec 22 20:
57 /usr/local
如果我们看一看从左起的第二栏,我们可以看到目录 /usr/local(索引节点 5120)被引用了 8 次。在我的系统中,引用该索引节点的不同路径有这些:
/usr/local
/usr/local/.
/usr/local/bin/..
/usr/local/games/..
/usr/local/lib/..
/usr/local/sbin/..
/usr/local/share/..
/usr/local/src/..
mkdir
我们来快速地看一看 mkdir 命令,它可以用来创建新目录。下面的示例创建了三个新目录:tic、tac 和 toe,都在 /tmp 下:
$ cd /tmp
$ mkdir tic tac toe
缺省情况下,mkdir 不会为您创建父目录;邻接的上一元素的完整路径必须存在。因此,如果您想要创建目录 won/der/ful,您将需要发出三个单独的 mkdir 命令:
$ mkdir won/der/ful
mkdir: cannot create directory
`won/der/ful': No such file or directory
$ mkdir won
$ mkdir won/der
$ mkdir won/der/ful
mkdir -p
然而,mkdir有一个很方便的-p选项,该选项告诉mkdir创建所有缺少的父目录,如下所示:
$ mkdir -p easy/as/pie
总之,非常简单。要学习更多关于 mkdir 命令的知识,请输入 man mkdir 来阅读手册页。除 cd(它内置在 bash 中)之外,这几乎适用于这里所涉及的所有命令(比如 man ls)。
touch
现在,我们将要快速地看一看 cp 和 mv 命令,这些命令用来复制、重命名以及移动文件和目录。为了开始该概述,我们将首先用 touch 命令在 /tmp 中创建一个文件:
$ cd /tmp
$ touch copyme
如果文件存在,touch 命令将更新文件的“mtime”(请回想 ls -l 输出中的第六栏)。如果文件不存在,那么将创建一个新的空文件。现在您应该有一个大小为零的 /tmp/copyme 文件。
echo 和重定向
既然文件存在,我们来把一些数据添加到文件中。我们可以使用echo命令来完成,它带有自己参数,并且把这些参数打印到标准输出。首先,单独的 echo 命令是这样的:
$ echo \"firstfile\"
firstfile
带有输出重定向的同样的 echo 命令为:
$ echo \"firstfile\" > copyme
大于符号告诉 shell 将 echo 的输出写到名为 copyme 的文件中。如果该文件不存在,将创建这个文件;如果该文件存在,将覆盖这个文件。通过输入 ls -l,我们可以看到 copyme 文件为 10 个字节长,因为它包括 firstfile 这个词和换行符:
$ ls -l copyme
-rw-r--r-- 1 root root 10 Dec 28 14:13 copyme
cat 和 cp
为了在终端显示文件的内容,要使用 cat 命令:
$ cat copyme
firstfile
现在,我们可以使用 cp 命令的基本调用来由原始的 copyme 文件创建 copiedme 文件:
$ cp copyme copiedme
通过观察,我们发现它们确实是相互独立的文件;它们的索引节点号不同:
$ ls -i copyme copiedme
648284 copiedme 650704 copyme
mv
现在,我们来用“mv”命令将“copiedme”重命名为“movedme”。其索引节点号将仍然是同一个;但是,指向该索引节点的文件名将改变。
$ mv copiedme movedme
$ ls -i movedme
648284 movedme
只要目标文件和源文件驻留在同一文件系统上,被移动的文件的索引节点号就将仍然不变。在本教程系列的第 3 部分,我们将进一步看一下文件系统。
创建链接和删除文件
硬链接
当谈及目录条目和索引节点之间关系时,我们提到了链接这个术语。Linux 实际有两种链接。到此为止我们所讨论的这种链接叫硬链接。一个给定的索引节点可以有任意数目的硬链接,该索引节点一直存在于文件系统,直到所有的硬链接消失。可以使用 ln 命令来创建新的硬链接
$ cd /tmp
$ touch firstlink
$ ln firstlink secondlink
$ ls -i firstlink secondlink
15782 firstlink 15782 secondlink
您可以看到,硬链接工作于索引节点级别,指向特殊的文件。在 Linux 系统上,硬链接有几个局限性。第一,您只能给文件建立硬链接,而不能给目录建立硬链接。的确如此;即便 . 和 .. 是系统给目录创建的硬链接,也不允许您(“root”用户也不行)创建任何您自己的硬链接。
硬链接的第二个局限性是它们不能跨文件系统。这意味着,如果您的 / 和 /usr 存在于不同的文件系统,您不能创建从 /usr/bin/bash 到 /bin/bash 的链接。
符号链接
实际上,符号链接(symbolic link,或“symlinks”)比硬链接更常用到。符号链接是一种专门的文件类型,在这种文件类型中,链接通过名称引用另一个文件,而不是直接引用索引节点。符号链接不阻止文件被删除;如果目标文件消失,那么符号链接仅仅是不可用,或“被破坏”。
通过将 -s 选项传给 ln,可以创建符号链接。
$ ln -s secondlink thirdlink
$ ls -l firstlink secondlink thirdlink
-rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:
08 firstlink
-rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:
08 secondlink
lrwxrwxrwx 1 agriffis agriffis 10 Dec 31 19:
39 thirdlink -> secondlink
在 ls -l 输出中,可以用三种方式区分符号链接和一般文件。第一,请注意第一栏包含一个 l 字符的输出表明是符号链接。第二,符号链接的大小是目标文件(本例是 secondlink)的字符数。第三,输出的最后一栏显示目标文件名。
符号链接通常比硬链接更灵活。您可以给任何类型的文件系统对象(包括目录)创建符号链接。又因为符号链接的实现是基于路径的(而不是索引节点),所以创建指向另一个文件系统上的对象的符号链接是完全可行的。但是,这一事实也使符号链接理解起来很复杂。请考虑我们想要在/tmp中创建一个指向/usr/local/bin的链接的情况。我们应该输入:
$ ln -s /usr/local/bin bin1
$ ls -l bin1
lrwxrwxrwx 1 root root 14 Jan 1 15:
42 bin1 -> /usr/local/bin
或者还可以输入:
$ ln -s ../usr/local/bin bin2
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:
43 bin2 -> ../usr/local/bin
您可以看到,两个符号链接都指向同一目录。但是,如果我们的第二个符号链接在任何时刻被移动到另一个目录,由于相对路径的缘故,它将遭到“破坏”。
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:
43 bin2 -> ../usr/local/bin
$ mkdir mynewdir
$ mv bin2 mynewdir
$ cd mynewdir
$ cd bin2
bash: cd: bin2: No such file or directory
因为/tmp/usr/local/bin这个目录不存在,我们不能再把目录转到bin2;换句话说,bin2 现在被破坏了。
由于这个原因,有时避免用相对路径信息来创建符号链接是个好主意。但是,在许多情况下,相对的符号链接很管用。请考虑一个示例,在这个示例中您想要给 /usr/bin 中的一个程序创建一个别名:
# ls -l /usr/bin/keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/bin/keychain
作为 root 用户,您可能想要给“keychain”创建一个别名,比如“kc”。在这个示例中,我们有 root 访问权,由 bash 提示符改变为“#”可以证明。我们之所以需要 root 访问权是因为一般用户不能在 /usr/bin 中创建文件。作为 root 用户,我们可以像下面这样给 keychain 创建一个别名:
# cd /usr/bin
# ln -s /usr/bin/keychain kc
当这个解决方法起作用时,如果我们想要把两个文件都移到 /usr/local/bin 时,它将会出现问题。
# mv /usr/bin/keychain
/usr/bin/kc /usr/local/bin
因为在符号链接中,我们使用了绝对路径,而我们的kc符号链接仍然指向/usr/bin/keychain,它已不存在了??另一个被破坏的符号链接。符号链接中的相对路径和绝对路径都各具优点,您应该使用适合于您的特殊应用的路径类型。一般情况下,相对路径或绝对路径都能工作得很好。在这种情况下,下面的示例将起作用:
# cd /usr/bin
# ln -s keychain kc
# ls -l kc
lrwxrwxrwx 1 root root 8 Jan 5 12:
40 kc -> keychain
rm
既然我们知道怎样使用 cp、mv 和 ln,现在我们该学习怎样把对象从文件系统中删除了。通常,这用 rm 命令来完成。要删除文件,只需在命令行中指定它们:
$ cd /tmp
$ touch file1 file2
$ ls -l file1 file2
-rw-r--r-- 1 root root 0 Jan 1 16:41 file1
-rw-r--r-- 1 root root 0 Jan 1 16:41 file2
$ rm file1 file2
$ ls -l file1 file2
ls: file1: No such file or directory
ls: file2: No such file or directory
rmdir
要删除目录,您有两种选择。您可以删除目录中所有的对象,然后使用 rmdir 来删除目录本身:
$ mkdir mydir
$ touch mydir/file1
$ rm mydir/file1
$ rmdir mydir
rm 和目录
或者,您可以使用 rm 命令的 recursive force选项来告诉rm删除您指定的目录以及目录中包含的所有对象:
$ rm -rf mydir
一般情况下,rm -rf 是删除目录树的首选方法。在使用 rm -rf 时要十分小心,因为它的功能可以被很好地利用,也可能会因使用不当造成恶果。
介绍通配符
在您日常的 Linux 使用中,有很多时候您可能需要一次对多个文件系统对象执行单一操作(比如 rm)。在这些情况下,在命令行中输入许多文件通常让人感到厌烦,为了解决这个问题,您可以利用 Linux 内置的通配符支持。这种支持也叫做“globbing”(由于历史原因),允许您通过使用通配符模式一次指定多个文件。
Bash 和其它 Linux 命令将通过在磁盘上查找并找到任何与之匹配的文件来解释这种模式。因此,如果在当前工作目录中,您有从 file1 到 file8 的文件,那么您可以输入下面的命令来删除这些文件:
$ rm file[1-8]
或者,如果您只想要删除文件名以 file 开头的所有文件,您可以输入:
$ rm file*
理解不匹配
或者,如果您想要列出 /etc 中以 g 开头的所有文件系统对象,您可以输入:
$ ls -d /etc/g*
/etc/gconf /etc/ggi /etc/gimp /etc/gnome
/etc/gnome-vfs-mime-magic /etc/gpm
/etc/group /etc/group-
现在,如果您指定了没有任何文件系统对象与之匹配的模式,会怎么样呢?在下面的示例中,我们试图列出 /usr/bin 中以 asdf 开头并且以 jkl 结尾的所有文件:
$ ls -d /usr/bin/asdf*jkl
ls: /usr/bin/asdf*jkl:
No such file or directory
这里是对所发生情况的说明。通常,当我们指定一种模式时,该模式与底层系统上的一个或多个文件匹配,bash 以空格隔开的所有匹配对象的列表来替换该模式。
但是,当模式不能找到匹配对象时,bash 将不理会参数、通配符等等,保留原样。因此,当“ls”不能找到文件 /usr/bin/asdf*jkl 时,它会报错。此处的有效的规则是:glob 模式只在与文件系统中的对象匹配时才可以进行扩展.
前往红联论坛参与此主题的讨论 如果有疑问,请前往这里提交你的问题,我们将尽力帮你解决
红联论坛
__________________
希望能和你相互交流,愿意和您分享学习、进步中的每分喜悦与快乐
---------------------------------------------
http://tzhsuccess.itpub.net
向版主反映这个帖子 查看tzhsuccess 的IP地址
147楼 旧帖 06-07-17 23:39
[ 大 中 小 ] 给予该贴好评 编辑/删除 引用/回复
tzhsuccess
高级会员
注册日期: 2004 Apr
来自: 太?系-?子座
技术贴数:7934
论坛积分:31670
论坛排名:67
论坛徽章:23
会员2006贡献徽章 行业板块每日发贴之星 ERP板块每日发贴之星
从学习export命令理解到的Shell环境和变量生存期
执行一个脚本时,会先开启一个子shell环境(不知道执行其它程序是不是这样),然后将父shell中的所有系统环境变量复制过来,这个脚本中的语句就在子shell中执行。(也就是说父shell的环境变量在子shell中可以调用,但反过来就不行,如果在子shell中定义了环境变量,只对该shell或者它的子shell有效,当该子shell结束时,也可以理解为脚本执行完时,变量消失。)为了证明这一点,请看脚本内容:
test='value'
export test
这样的脚本执行完后,test实际上是不存在的。接着看下面的:
test='value'
export test
bash
这里在脚本最后一行再开一个子shell,该shell应该是脚本文件所在shell的子shell,这个脚本执行完后,是可以看到test这个变量的,因为现在是处于它的子shell中,当用exit退出子shell后,test变量消失。
如果用source对脚本进行执行时,如果不加export,就不会在子shell中看到这个变量,因为它还不是一个系统环境变量呀,如脚本内容是:
test='value'
用source执行后,在shell下是能看到这个变量,但再执行bash开一个子shell时,test是不会被复制到子shell中的,因为执行脚本文件其实也是在一个子shell中运行,所以我再建另一个脚本文件执行时,是不会输入任何东西的,内容如:echo $test。所以这点特别注意了,明明在提示符下可以用echo $test输出变量值,为什么把它放进脚本文件就不行了呢?
所以得出的结论是:1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;2、一个shell中的系统环境变量才会被复制到子shell中(用export定义的变量);3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失(并不能返回到父shell中)。3、不用export定义的变量只对该shell有效,对子shell也是无效的。
后来根据版主的提示,整理了一下贴子:为什么一个脚本直接执行和用source执行不一行呢?这也是我自己碰到的一个问题。manual原文是这样的:Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.明白了为什么不一样了吧?直接执行一个脚本文件是在一个子shell中运行的,而source则是在当前shell环境中运行的。