set 是 shell 内置命令之一,它可以用来设置 shell 的相关选项以及环境变量等。当运行不带任何参数的 set 命令时,会列出所有的变量。
下面是 set 命令的一些选项:
-n :只读取脚本,但不实际执行。
这个选项常用于在脚本的调试阶段发现脚本中的语法错误,像 make 一个 Makefile 文件时,经常也会用到此选项。比如 make -n ,又如 sh -n example.sh ,这里实际上都是调用了 set 这个选项。如下面检查一个有语法错误的脚本:
引用[beyes@localhost shell]$ sh -n menu.sh
menu.sh: line 8: unexpected EOF while looking for matching `''
menu.sh: line 10: syntax error: unexpected end of file
-x :进入跟踪方式,这样会显示出脚本执行每一条命令及其参数。这个选项在调试脚本时也是相当有用的。比如下面一个脚本内容为:
1
2
3
4
5
6
|
#!/bin/bash
echo
"hello"
echo
"world"
date
ls
-al
|
带有 -x 选项的运行:
引用[beyes@localhost shell]$ sh -x menu.sh
+ echo hello
hello
+ echo world
world
+ date
Sun May 29 18:53:43 PDT 2011
+ ls -al
total 12
drwxrwxr-x. 2 beyes beyes 4096 May 29 18:53 .
drwx------. 25 beyes beyes 4096 May 29 18:53 ..
-rw-rw-r--. 1 beyes beyes 249 May 29 18:53 menu.sh
在上面的输出中,每条被执行的命令前面都有一个 "+" 号。也可以将 set -x 这条命令放入脚本中,那么在 shell 中执行这个脚本时,只需要 sh menu.sh 或者脚本有可执行权限时直接 ./menu.sh ,这样也能在输出时看到被跟踪的命令。
-e :如果命令带有非 0 值就会立即退出。在 shell 中,一个表达式为真或者一条命令成功执行,那么会返回 0 值。看下面的脚本执行情况:
1
2
3
4
5
6
7
8
|
#!/bin/bash
echo
"hello"
echo
"world"
ifdown eth0
#普通用户没有权限配置网卡
date
|
直接运行脚本:
引用[beyes@localhost shell]$ sh menu.sh
hello
world
Users cannot control this device.
Sun May 29 19:01:18 PDT 2011
带有 -e 选项运行脚本:
引用[beyes@localhost shell]$ sh -e menu.sh
hello
world
Users cannot control this device.
对比两者的输出,带有 -e 选项的运行方式使脚本在运行在 ifdown eth0 这条命令时脚本退出了,因为普通用户没有权限禁用网卡,所以此命令执行必然失败,从而返回值为非零。
-f / +f :取消与恢复通配符(man 手册里说 Disable file name generation,这里 file name generation 就是通配符的意思)。注意,在使用 set 命令时,具有开关作用的选项,选项前面为 "-" 号的为“关闭”,选项前面有 "+" 的为“打开”。
引用[beyes@localhost shell]$ ls *.sh
ls: cannot access *.sh: No such file or directory
[beyes@localhost shell]$ set +f
[beyes@localhost shell]$ ls *.sh
menu.sh
在上面的例子中,在使用 -f 后,无法展开通配符 "*" 号;使用 "+f" 恢复后,即可恢复通配符的功能。
-C :不允许输出重定向覆盖已有的文件。如:
引用[beyes@localhost shell]$ set -C
[beyes@localhost shell]$ touch file1
[beyes@localhost shell]$ echo "hello world" > file1
bash: file1: cannot overwrite existing file
[beyes@localhost shell]$ set +C
[beyes@localhost shell]$ echo "hello world" > file1
set 命令还有一个比较有用的 -o 选项,它后面接选项名,这些选项名就是上面选项的完整名字。
其中有一个 vi 的选项名更显实用,比如:
set -o vi ,你就可以在敲打命令时使用具有 vi 风格的编辑方法。比如在默认情况下,可能在敲打一个长命令时,当走到命令末位,忽然发现命令的前部写错了点什么然后要返回时,不得不按左键一直往回走,这样就可能比较费时了。如果事先使用了 set -o vi ,那么你要回到命令头部时,只要跟 vi 里编辑一样,先按下 ESC 键,然后再按下 Shift + ^ 组合键即可。
下面是 -o 可接的选项名:
选项名 | 快捷键开关 | 含义 |
allexport | -a | 从这个选项被设置开始就自动标明要输出的新变量或修改过的变量,直至选项被复位 |
braceexpand | -B | 打开花括号扩展,是一个缺省设置 |
emacs | 使用emacs内置编辑器进行命令行编辑,是一个缺省设置 | |
errexit | -e | 当命令返回一个非0退出状态(失败)时退出,读取初始化文件时不设置 |
histexpand | -H | 执行历史替换时打开!和!!扩展,是一个缺省设置 |
history | 打开命令行历史;缺省为打开 | |
ignoreeof | 禁止用EOF(Control-D)键退出shell;必须输入exit才能退出。和设置shell变量IGNOREEOF=10一样 | |
keyword | -k | 将关键字参数放到命令的环境中 |
interactive-comments | 对于交互式shell,#用来将后面的文件作为注释 | |
monitor | -m | 设置作业控制 |
noclobber | -C | 防止文件在重定向时被重写 |
noexec | -n | 读命令,但不执行。用来检查脚本的语法。交互式运行时不设置 |
noglob | -d | 禁止用户路径名扩展;即关闭通配符 |
notify | -b | 通知用户什么时候后台作业完成 |
nounset | -u | 扩展一个没有设置的变量时显示一个错误信息 |
onecmd | -t | 在读取和执行命令后退出 |
physical | -P | 设置时,在键入cd或pwd时禁止符号连接。用物理目录代替 |
posix | 如缺省操作不符合POSIX标准就改变shell行为 | |
privileged | -p | 设置时,shell不读,profile或ENV文件,且不从环境继承shell函数;自动为setuid脚本开启特权 |
verbose | -v | 为调试打开verbose模式 |
vi | 使用vi内置编辑器进行命令行编辑 | |
xtrace | -x | 为调试打开[font='bitstream]跟踪模式 |
默认情况下,按下 ctrl + d 组合键会发出 EOF ,从而退出终端。比如在打开一个终端窗口时,按下 ctrl + d ,终端窗口关闭。如果此时不希望这样,那么就用
set -o ignoreeof
这时你如果按下 ctrl + d 时,shell 会提示你:
引用[beyes@localhost ~]$ set -o ignoreeof
#按下 ctrl + d
[beyes@localhost ~]$ Use "exit" to leave the shell.
所以此时需要用 exit 命令退出终端。如果希望恢复,那么就用 set +o ignoreeof 。