您的位置:首页 > 运维架构 > Shell

Bash - the shell (2)

2011-10-29 17:01 239 查看

1. 更改bash为vi模式

bash默认是使用emacs模式,就是说在命令行编辑命令的很多快捷键是和emacs一样的(快捷键《bash-the shell(1)》中讲过了)。但是除了emacs,另外一个神器就是vi(vim)。vi是一个遵循POSIX的文本编辑器,因此如果需要让shell具有模式兼容性的话,让bash工作在vi模式是很有必要的。使用以下命令切换bash的模式:

$ set -o vi (开启vi模式,关闭emacs模式)
$ set -o emacs (开启emacs模式,关闭vi模式)
只用“set -o”,而不加参数,可以列出所有的选项。虽然习惯用vim作为编辑器,但是还是觉得bash的emacs模式比较顺手……

2. shell变量

shell变量也就是前一次的文章中提到的环境变量。如果在一个shell中再打开一个shell(可以看作为子shell),这些变量的值是可以继承的。但在子shell里更改环境变量的值,不会影响到父shell。给个例子说明:

$ echo $SHLVL
1
$ export TEST="hello,shell"
$ echo $TEST
hello,shell
$ bash
$ echo $SHLVL
2
$ echo $TEST
hello,shell
$ unset TEST
$ echo $TEST

$ exit
exit
$ echo $TEST
hello,shell
$SHLVL表示shell嵌套调用的次数。从上面的例子可以看出,子shell继承了TEST的值。但是在子shell中取消TEST变量,退出子shell后,在父shell中TEST的值仍然存在。

命令“env”可以用来查看环境变量。和用户自己定义的一些shell变量不同,这些环境变量将构成可执行程序执行的环境,并且可以通过exec系列函数,给需要运行的命令或程序提供一个环境。虽然环境变量这个东西很有用处,但是在开发的时候,它也可能带来一些副作用。所以在做开发的时候,可以把环境变量保存下来,以便很长一段时间以后还可以在查看,并且可以恢复这个环境变量。

“env”也可以用来让一个程序执行在不受环境变量影响的环境中。这可以用来测试一个命令或者应用程序能否在不同的环境中运行,而不依赖于某些特殊的设置。“env -i”可以在忽略环境变量的情况下执行命令。看例子,我电脑上/opt下有一个arm的交叉编译环境。我在~/.bashrc中,给PATH变量添加了arm交叉编译环境的路径:

export PATH="$PATH:/opt/CodeSourcery/bin"
直接在命令行输入arm-none-linux-gnueabi-gcc -v可以查看交叉编译gcc的版本信息:

$ ls /opt/CodeSourcery/bin/arm-none-linux-gnueabi-gcc
/opt/CodeSourcery/bin/arm-none-linux-gnueabi-gcc
$ arm-none-linux-gnueabi-gcc -v
Using built-in specs.
Target: arm-none-linux-gnueabi
... ...
gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202)
现在用“env -i”在试试看:

$ env -i arm-none-linux-gnueabi-gcc
env: arm-none-linux-gnueabi-gcc: No such file or directory


提示说找不到arm-none-linux-gnueabi-gcc,这说明在~/.bashrc中设置的环境变量没有起作用。要非常小心这些环境变量,它可能在你调试程序的时候给你带来很大的麻烦(不过我们一般写的简单的程序是不会受到什么影响的 :-D)。



3. 补全

Tab>: 按<Tab>键可以对命令或者文件名等补全。
$: <Tab>键也可以补全环境变量。例如输入“$SH”,然后连按两下<Tab>,就会显示所有以SH开头的环境变量,我这里显示“$SHELL $SHELLOPTS $SHLVL”。
@: 我们很少用<Tab>键来补全主机名。这个命令是用来补全在不使用DNS的情况下,系统所知道的主机名。这些主机名通常是定义在/etc/hosts这个文件中的。我的/etc/hosts文件中的内容显示如下:

#<ip-address>	<hostname.domain.org>	<hostname>
127.0.0.1		localhost.localdomain	localhost shyodx
因此,自动补全@,就显示为:

$ @ (此处连按两次<Tab>)
@localhost	@localhost.localdomain  @shyodx
当然,我们也可以无视系统默认的/etc/hosts文件。可以通过HOSTFILE变量来自己定义一个同样功能的文件。我们也可以按照/etc/hosts的文件格式,在hosts文件中添加一些ssh服务器的地址,这样用ssh的时候就方便多了,直接<Tab>就可以出来了。

~: 在命令行输入一个“~”符号,连按两次<Tab>就会列出/etc/passwd中的所有用户。

4. 大(花)括号

有时候一个命令的参数可能有些字符是重复的,在这种情况下,就可以使用大括号来作为列表操作符。

$ ls
main.c  test  test.c  test.db
$ ls {test,main}.c
main.c  test.c
$ ls test.{c,db}
test.c  test.db
这个操作符更常用的用法是在新建文件或者目录的时候:

$ mkdir -p ./{a,b,c/{c1,c2}}
$ tree
.
|-- a
|-- b
`-- c
|-- c1
`-- c2

5 directories, 0 files


5. 作业控制

把“&”符号放在要执行的命令的末尾,这个命令就可以后台执行

用<Ctrl>+z可以把程序放到后台执行

“fg”把后台执行的程序放到前台来

“bg”把一个程序放到后台执行
“jobs”列出该会话中,所有正在后台执行的程序

各个例子来看看,使用sleep命令让这个进程等待300秒,然后<Ctrl>+z,让这个进程停下来,并把它放到后台去,接着用bg命令让这个进程在后台接着执行。这时,我们就可以用jobs来列出当前会话中正在后台执行的程序。用“fg”来将刚才放入后台的进程调到前台来执行。

$ sleep 300
^Z
[1]+  Stopped                 sleep 300
$ bg 1
[1]+ sleep 300 &
$ jobs
[1]+  Running                 sleep 300 &
$ fg
sleep 300
^C
另外,在用后台执行的时候,通常会把执行的输出重定向到某一个文件或者/dev/null中去。这个后台执行程序貌似不经常用到,所以就不说太多……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: