linux如何加入内部指令,Linux内部命令和外部命令

Linux内部命令和外部命令

关于上篇777超级目录权限下的测试有不严谨的地方(最终结果不受影响),这部分知识点遗忘的厉害,所以特别总结这篇文章。

上篇文章中最大的问题是忽略了BASH的内部命令和外部命令,本篇文章重点论述Linux内部命令和外部命令的相关知识体系。

以echo为例,下面三种方式执行方式是有很大区别的# 方式一

enable echo

echo "abc"

# 方式二

enable -n echo

echo "abc"

# 方式三

/bin/echo方式一

默认调用的是BASH SHELL内置命令echo来直接运行该命令,无需fock子shell。

方式二

执行enable -n echo关闭BASH SHELL内部echo命令,即根据系统环境变量顺序查找echo命令,而后执行。

方式三

该方式,无需查找环境变量,而是直接执行/bin/echo命令。

那么Linux下究竟如何查找并运行命令呢?什么是内部命令和外部命令,为什么会有内部命令和外部命令?如何区别内部命令和外部命令呢?我们逐一来看

1. 什么是内部命令和外部命令

Linux命令有内部(建)命令和外部命令之分,内部命令和外部命令功能基本相同,但有些细微差别。所谓的内部和外部其实是相对SHELL自身来讲。Linux系统为了提高系统运行效率,将经常使用的轻量的命令在系统启动时一并加载这些命令到内存中供SHELL随时调用,这部分命令即为内部命令。反之,系统层调用的较重的命令只有当被调用时才会硬盘加载的这部分命令即为外部命令。(1)内部命令实际上是shell程序的一部分,其中包含的是一些比较简单的linux系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bashy源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程。比如:exit,history,cd,echo等。

(2)外部命令是linux系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调用内存。通常外部命令的实体并不包含在shell中,但是其命令执行过程是由shell程序控制的。shell程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。外部命令是在bash之外额外安装的,通常放在/bin,/usr/bin,/sbin,/usr/sbin……等等。可通过“echo $PATH”命令查看外部命令的存储路径,比如:ls、vi等。

2. 如何区别内部命令和外部命令

日常工作中,对于系统用户来讲其实很少关注内部命令和外部命令,只要使得顺手正常,很少有人去关注这部分内容。但在环境复杂或系统状态异常(被***)等情况下,我们更建议使用绝对路径下的外部命令。当然,Linux系统也提供了相关命令来区别二者,type区分内部命令与外部命令。

用法如下:type: type [-afptP] name [name ...]

Display information about command type.

For each NAME, indicate how it would be interpreted if used as a

command name.

Options:

-a        display all locations containing an executable named NAME;

includes aliases, builtins, and functions, if and only if

the `-p' option is not also used

-f        suppress shell function lookup

-P        force a PATH search for each NAME, even if it is an alias,

builtin, or function, and returns the name of the disk file

that would be executed

-p        returns either the name of the disk file that would be executed,

or nothing if `type -t NAME' would not return `file'.

-t        output a single word which is one of `alias', `keyword',

`function', `builtin', `file' or `', if NAME is an alias, shell

reserved word, shell function, shell builtin, disk file, or not

found, respectively

Arguments:

NAME      Command name to be interpreted.

Exit Status:

Returns success if all of the NAMEs are found; fails if any are not found.

常用的三个参数:-t对应-type

-a对应-all

-p对应-path

使用:type [-a | -t | -p] name 或 type [-all | -type | -path] name。(1)没有参数的状况下,它会显示出shell如何解译name做为命令。

(2)如果有”-type”,它将会显示alias、 keyword、function、builtin或file。file:表示为外部指令;

alias:表示该指令为命令别名所设定的名称;

builtin:表示该指令为 bash 内建的指令功能。

(3)如果有”-path”的参数,它将会显示该命令的完整档名(外部指令)或显示为内建指令,找不到的话,不显示任何东西。

(4)如果有”-all”的参数,会将由PATH变量定义的路径中所有含有name指令的路径都列出来,即显示所有可执行name的可能路径。

例如1:[%23%root@192 ~]# type cd

cd is a shell builtin #这里可以看出cd是一个内部命令

例如2:[%24%root@192 ~] type ls

ls is aliased to `ls --color=auto' # 没有加上任何参数,仅列出 ls 这个指令的最主要使用情况

[%25%root@192 ~] type -t ls

alias # -t 参数则仅列出 ls 这个指令的最主要使用情况说明

例如3:[%26%root@192 ~] type -a ls

ls is aliased to `ls --color=auto'

ls is /bin/ls # 列出所有信息:这里可以看出ls是一个外部命令。

3. 为什么会内部命令和外部命令

内部命令其实是SHELL程序的一部分,其中包含的是一些比较简练和日常经常会被用到的命令。这些命令通常系统启动时就调入内存,且常驻内存的,由SHELL程序识别并在SHELL程序内部运行,之所以这样做的原因只有一个就是:为了最大化执行效率,提升系统性能。而 外部命令通常是系统的软件功能,该部分程序功能通常较为强大,但包括的程序量也很大,因此并不随系统启动一并加载,只在用户需要时才从硬盘中读入内存。

4. 内部命令和外部命令的区别

因为内部命令是SHELL内置,所以该命令调用时直接使用,无需追踪环境变量,而外部命令则有很大区别,因为外部命令如希望被用户所使用,依然要通过SHELL程序来调用,所以多了一层执行路径的问题,即我们常讲到的环境变量。

外部命令就是由Shell副本(新的进程)所执行的命令,基本的过程如下:a. 建立一个新的进程。此进程即为Shell的一个副本。

b. 在新的进程里,在PATH变量内所列出的目录中,寻找特定的命令。

/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin为PATH变量典型的默认值。

当命令名称包含有斜杠(/)符号时,将略过路径查找步骤。

c. 在新的进程里,以所找到的新程序取代执行中的Shell程序并执行。

d. 程序完成后,最初的Shell会接着从终端读取下一条命令,和执行脚本里的下一条命令。

通常情况下,脚本中的Bash内建命令在运行的时候是不会fork出一个子进程的。但是脚本中的外部或者过滤命令通常会fork出一个子进程。 一个内建命令通常会与一个系统命令同名,但是Bash在内部重新实现了这些命令。比如,Bash的echo命令与/bin/echo就不尽相同,虽然它们的行为在绝大多数情况下都是一样的。

同理,如果我们内部命令对应的外部存放mv到系统环境变量之外的其它目录下或者rm掉。该命令其实仍然可以被执行的,因为其查找的顺序是内部命令->外部命令,看下面的这个小实验:[%27%root@192 ~]# which cd

/usr/bin/cd  ## 外部cd二进制文件存放在该目录下

[%28%root@192 ~]# mv /usr/bin/cd /usr/bin/cd.move   ## 改名

[%29%root@192 ~]# cd /usr/   ## 改名后依然可以正常执行

[%30%root@192 /usr]# cd -

/root

[%31%root@192 ~]# type cd

cd is a shell builtin   ## cd 是内部命令

shell命令解释器在执行命令时,先尝试按照内部命令来执行,如果要执行的命令不是内部命令,则按照外部命令去查找对应的执行文件所在的目录,并执行。当要执行的命令不是内部命令时(例如ls),如果有两个ls指令分别在不同的目录中(例如/usr/local/bin/ls和/bin/ls),shell命令解释器就根据PATH里面哪个目录先被查询到,则那个目录下的命令就先被执行。

5. 查看和关闭内部命令

SHELL中的内置命令约有60个,通过内置的enable命令即可查看所有的内部命令[%66%root@192 ~]# enable

enable .

enable :

enable [

enable alias

enable bg

enable bind

enable break

enable builtin

enable caller

enable cd

enable command

enable compgen

enable complete

enable compopt

enable continue

enable declare

enable dirs

enable disown

enable echo

enable enable

enable eval

enable exec

enable exit

enable export

enable false

enable fc

enable fg

enable getopts

enable hash

enable help

enable history

enable jobs

enable kill

enable let

enable local

enable logout

enable mapfile

enable popd

enable printf

enable pushd

enable pwd

enable read

enable readarray

enable readonly

enable return

enable set

enable shift

enable shopt

enable source

enable suspend

enable test

enable times

enable trap

enable true

enable type

enable typeset

enable ulimit

enable umask

enable unalias

enable unset

enable wait

其中内部命令没有专门的man文档和help说明。即执行如下命令不会得到想要的帮助文档[%73%root@192 ~]# cd -h

-bash: cd: -h: invalid option

cd: usage: cd [-L|[-P [-e]]] [dir]

[%74%root@192 ~]# cd --help

-bash: cd: --: invalid option

cd: usage: cd [-L|[-P [-e]]] [dir]

[%75%root@192 ~]# man cd

BASH_BUILTINS(1)              General Commands Manual             BASH_BUILTINS(1)

NAME

bash,  :, ., [, alias, bg, bind, break, builtin, caller, cd, command, comp‐

....

内容较多,不一一列举

一般内部命令使用help COMMAND如下命令获取帮助文档# help command

以enable命令为例:[%77%root@192 ~]# help enable

enable: enable [-a] [-dnps] [-f filename] [name ...]

Enable and disable shell builtins.

Enables and disables builtin shell commands.  Disabling allows you to

execute a disk command which has the same name as a shell builtin

without using a full pathname.

Options:

-a        print a list of builtins showing whether or not each is enabled

-n        disable each NAME or display a list of disabled builtins

-p        print the list of builtins in a reusable format

-s        print only the names of Posix `special' builtins

Options controlling dynamic loading:

-f        Load builtin NAME from shared object FILENAME

-d        Remove a builtin loaded with -f

Without options, each NAME is enabled.

To use the `test' found in $PATH instead of the shell builtin

version, type `enable -n test'.

Exit Status:

Returns success unless NAME is not a shell builtin or an error occurs.

enable -n cd 表示禁用命令cd在SHELL中的内置功能。[%88%root@192 ~]# cd /usr/bin/

[%89%root@192 /usr/bin]# mv cd cd.move

[%90%root@192 /usr/bin]# pwd

/usr/bin

[%91%root@192 /usr/bin]# enable  -n cd

[%92%root@192 /usr/bin]# cd /tmp

-bash: /usr/bin/cd: No such file or directory

[%93%root@192 /usr/bin]# enable cd

[%94%root@192 /usr/bin]# cd /tmp

[%95%root@192 /tmp]# pwd

/tmp

89272c572fa733d1ec94a17478978eba.png

OK,至此内部命令和外部命令希望我讲的还算明白

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值