shell 学习三十九天----内建命令
内建命令
shell 识别三种基本命令:内建命令,shell 函数以及外部命令:
- 内建命令就是有 shell 本身所执行的命令。
有些命令是由于其必要性才内建的,例如
cd
用来改变目录,read
会将来自用户 (和文件) 的输入数据传给 shell 外壳。另一种内奸命令的存在则是为了效率,其中最典型的就是test
命令,编写脚本时经常会用到它。另外还有I/O
命令,例如echo
与printf
。 - shell 函数是功能健全的一系列程序代码,以 shell 语言写成,他们可以像命令那样引用。
-
外部命令就是由 shell 副本 (新的进程) 所执行的命令,基本的过程如下:
- 3.1. 建立一个新的进程。此进程即为 shell 的一个副本
- 3.2. 在新的进程里,在
PATH
变量内所列出的目录中,需找特 定命令。/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/u sr/sbin:/usr/bin:/root/bin
为PATH
变量典型的默认值 当命令名称含有斜杠(/)
字符时,将略过路径查找步骤。 - 3.3. 在新的进程里,以所找到的新程序取代执行中的 shell 程序并执行
- 3.4. 程序完成后,最初的 shell 会接着从终端读取下一条命令,和执行脚本里的吓一跳命令。
使用 type 可以查看是否是内建命令
type(不带参数) 会显示命令是内建的还是外部的。
-t
:file
外部命令;alias
命令别名;builtin
内置命令-a
:会将命令 PATH 路径显示出来。
如何执行交互式命令:
用户在输入命令后,一般情况下 shell 会解释并执行该命令,但是 shell 的内建命令例外,执行内建命令相当于调用 shell 进程的一个函数,并不创建新的进程。
比如:cd
,alias
,umask
,exit
等命令及时内建命令,凡是用 which
命令查不到程序文件所在位置的命令都是内建命令,内建命令没有单纯的 man 手册,要在 man 手册中查看内奸命令,应该 man bash-builtins
,内建命令虽然不创建新的进程,但也会有 Exit Static
,通常也用 0 表示成功非零表示失败,虽然内建命令不创建新的进程,胆汁性结束后也有一个状态吗,也可以用特殊变量 $?
读出。
command 命令
语法:
command [-p] program [arguments....]
用途:
在查找要执行的命令时,为了避开 shell 的包含函数。这允许从函数中访问与内建命令同名的内建版本。
主要选项:
-p
:当查找命令是,使用$PATH
的默认值,保证找到系统的工具
行为:
command 会通过查阅特殊的与一般的内建命令,已找出指定的 program,并沿着 $PATH
查找。使用 -p
选项,则会使用 $PATH
的默认值,而非当前的设置。
如果 program 为特殊内建命令,责任和的语法错误都不会退出 shell,且任何前置的变量指定在命令完成后,即不再有效。
案例:
命令:echo linux
输出:linux
命令:command echo linux
输出:linux
command
命令调用指定的指令并执行,命令执行时不查询 shell 函数。command
命令只能够执行 shell 内部的命令
POSIX 标准为特殊内建命令提供了两个附加特性:
- 特殊内建工具语法上的错误,会导致 shell 执行该工具时退出,然而当语法错误出现在一般内建命令时,并不会导致 shell 执行该工具时退出。如果特殊内建工具遇到语法错误时不退出 shell,则它的退出值应该非零。
- 以特殊内建命令所标明的变量指定,在内建命令完成
第二项需要解释一下,我们可以在命令前制定一个变量赋值,且变量值在被执行命令的环境中不影响当前 shell 内的变量或是接下来的命令:
PATH=/bin:/usr/bin:/usr/ucb awk '...'
然而,当这样的指定用于特殊内建命令时,及时在特殊内建命令之后,仍然会有影响。
wait
命令是用来等待后台程序完成的。如果未加任何参数,wait
会等待所有的后台工作完成;否则,每个参数可以是后台工作的进程编号,或是工作控制的工作规格。
.(点号)
也是很重要的命令。它是用来读取与执行包含在个别文件中的命令。例如:当你有很多歌 shell 函数想要在多个脚本中使用时,正确方式是将他们放在各自的库文件里,再以点号命令读取他们:
. my_funcs #在函数中读取
如指定的文件未含斜杠,则 shell 会查找 $PATH
下的目录,以找到该文件。该文件无需是可执行的,只要是可读取的即可。
set 命令
set
命令最简单的工作就是以排序的方式显示所有的 shell 变量的名称与值。这是调用它时不加任何参数与选项的行为。其输出是采用 shell 稍后可以重读的形式 ---- 包含适当的引号。这个想法是出自 shell 脚本有可能需要存储他的状态,在之后会通过.(点号) 命令恢复它。
set
的另一项任务是改变位置参数 ($1
,$2
等)。使用 -- 的第一个参数来结束设置它自己的选项,则所有接下来的参数都会取代位置参数,及时他们是以正号或负号开头。
set
的功能描述:
设置 shell
语法:
set [+-abCdefhHklmnpPtuvx]
补充说明:
用 set
命令可以设置各种 shell 选项或者列出 shell 变量。单个选项设置常用的特性。在某些选项之后 -o
参数将特殊特性打开。在某些选项之后使用 +o
参数将关闭某些特性,不带任何参数的 set
命令将显示 shell 的全部变量。除非遇到非法的选项,否则 set 总是返回 ture。
行为:
- 无选项或参数,则以 shell 少后可读取的形式来打印所有 shell 变量的名称与值。
- 选项为
--
及参数,则以提供的参数取代位置参数 - 开头为
-
的短选项,或以-o
开头的长选项,则可打开特定的 shell 选项,额外的非选项参数可设置位置参数。 - 以
+
开头的短选项,或以+o
开头的长选项,则可关闭特定的 shell 选项。 - 单一的
-o
可以一种不特别指定的格式打印 shell 选项的当前设置。 - 单一的
+o
则是显示 shell 选项的当前设置,其采用 shell 之后可以重读的方式,以获得选项的相同设置。
最后,set
被用来打开或停用 shell 选项,指的是改变 shell 行为模式的内部设置。
o 形式 短选项 说明
allexport -a 从设置开始标记所有新的和修改过的用于输出的变量
braceexpand -B 允许符号扩展,默认选项
emacs 在进行命令编辑的时候,使用内建的 emacs 编辑器,默认选项
errexit -e 如果一个命令返回一个非 0 退出状态值 (失败),就退出.
histexpand -H 在做临时替换的时候允许使用! 和!! 默认选项
history 允许命令行历史,默认选项
ignoreeof 禁止 coontrol-D 的方式退出 shell,必须输入 exit。
interactive-comments 在交互式模式下,#用来表示注解
keyword -k 为命令把关键字参数放在环境中
monitor -m 允许作业控制
noclobber -C 保护文件在使用重新动向的时候不被覆盖
noexec -n 在脚本状态下读取命令但是不执行,主要为了检查语法结构。
noglob -d 禁止路径名扩展,即关闭通配符
notify -b 在后台作业以后通知客户
nounset -u 在扩展一个没有的设置的变量的时候,显示错误的信息
onecmd -t 在读取并执行一个新的命令后退出
physical -P 如果被设置,则在使用 pwd 和 cd 命令时不使用符号连接的路径 而是物理路径
posix 改变 shell 行为以便符合 POSIX 要求
privileged 一旦被设置,shell 不再读取.profile 文件和 env 文件 shell 函数也不继承任何环境
verbose -v 为调试打开 verbose 模式
vi 在命令行编辑的时候使用内置的 vi 编辑器
xtrace -x 打开调试回响模式
扩展:
set
,env
和 export
这三个命令都可以用来显示 shell 变量,区别是:
set
用来显示本地变量env
用来显示环境变量export
用来显示和设置环境变量set
显示当前 shell 的变量,包括当前用户的变量env
显示当前用户的变量export
显示当前到处成用户变量的 shell 变量
每个 shell 有自己特有的变量 (set) 显式的变量,这个和用户变量不同,当前用户变量和你用什么 shell 无关,不管你用什么 shell 都在,比如 HOME
,SHELL
这些变量,但 shell 自己的变量在不同的 shell 是不同的,比如 BASH_ARGC
,BASH
等,这些变量只有 set 才会显示,是 bash 特有的,export
不加参数的时候,显示哪些变量被到处成了用户变量,因为一个 shell 自己 Ian
量可以通过 export
导出变成一个用户变量。
[root@linux ~]# aaa=bbb
[root@linux ~]# echo $aaa
bbb
[root@linux ~]# set|grep aaa
aaa=bbb
[root@linux ~]# env|grep aaa
[root@linux ~]# export aaa
[root@linux ~]# env|grep aaa
aaa=bbb
set
,env
,export
----linux 中的环境变量命令
linux 是一个多用户的操作系统。每个用户登录系统之后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。
什么是环境变量
环境变量是一个具有特定名字的对象,它包含了一个或多个应用程序所使用到的信息。通过使用环境变量,可以很容易的修改一个牵扯到一个或多个应用程序的配置信息。
常见的环境变量
对于 PATH 和 HOME 等环境变量大家都不陌生。
PATH 能够指定命令的搜索路径,那么动态链接库的路径用什么指定呢? 或者就是在 PATH 里面? 比如有一个程序需要 /usr/local/lib
下面的一个库文件,应该怎么指定其路径呢?
经常看到的某些变量:LD_LIBRARY_PATH
,LIBPATH
,CLASSPATH
等,他们之间有什么不同的关系?
HISTSIZE
是指保存历史命令记录的条数LOGNAME
是指当前用户的登录名HOSTNAME
是指主机的名称,许多程序如果要用到主机名的话,通常是从这个环境变量中来取得的SHELL
是指当前用户的用的是哪一种 shellLANG/LANGUGE
是和怨言相关的环境变量,使用多种语言的用户可以修改此环境变量MAIL
是指当前用户的邮件存放目录。PS1
是基本提示符,对于 root 用户是#
,度与普通用户是$.PS2
是附属提示符,默认是 “>”。可以通过修改此环境变量来修改当前的命令符。