初识Linux内置命令

文章详细讨论了Linuxshell中的内置命令read的工作原理,它如何接收参数并设置变量。通过`type`和`which`命令区分内置命令与系统命令,指出bash中的builtin命令旨在提高执行效率。同时,文章提到了`help`命令用于查看builtin命令的帮助信息,并以echo命令为例展示了如何区分内置命令与系统命令程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天查看linux脚本的时候发现一个命令read,原本脚本中使用read并没有什么问题,突然好奇read是怎么把最后一个参数设定为变量的。

which read
/usr/bin/read

ls -al /usr/bin/read
-rwxr-xr-x. 1 root root 28 Mar 31  2020 /usr/bin/read

平常使用的命令都是程序+参数,参数是传递给程序的main函数,通过识别main函数参数决定程序接下来要执行的流程,程序本身是二进制可执行文件。看到read命令本身大小只有28个字节,肯定不是二进制程序,于是看了一下read文件的内容

cat /usr/bin/read
#!/bin/sh
builtin read "$@"

看到这里发现read是个builtin命令,$@就是将参数全部传递到builtin read,包括最后一个代表变量的参数。既然是脚本,就可以按照脚本的方式新建变量。查阅了一部分builtin相关资料后发现linux终端提供了help命令,里面就是builtin命令

help
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 job_spec [&]                            history [-c] [-d offset] [n] or hist>
 (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
 . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
 :                                       kill [-s sigspec | -n signum | -sigs>
 [ arg... ]                              let arg [arg ...]
 [[ expression ]]                        local [option] name[=value] ...
 alias [-p] [name[=value] ... ]          logout [n]
 bg [job_spec ...]                       mapfile [-n count] [-O origin] [-s c>
 bind [-lpvsPVS] [-m keymap] [-f filen>  popd [-n] [+N | -N]
 break [n]                               printf [-v var] format [arguments]
 builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
 caller [expr]                           pwd [-LP]
 case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
 cd [-L|[-P [-e]]] [dir]                 readarray [-n count] [-O origin] [-s>
 command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
 compgen [-abcdefgjksuv] [-o option]  >  return [n]
 complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
 compopt [-o|+o option] [-DE] [name ..>  set [-abefhkmnptuvxBCHP] [-o option->
 continue [n]                            shift [n]
 coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
 declare [-aAfFgilrtux] [-p] [name[=va>  source filename [arguments]
 dirs [-clpv] [+N] [-N]                  suspend [-f]
 disown [-h] [-ar] [jobspec ...]         test [expr]
 echo [-neE] [arg ...]                   time [-p] pipeline
 enable [-a] [-dnps] [-f filename] [na>  times
 eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
 exec [-cl] [-a name] [command [argume>  true
 exit [n]                                type [-afptP] name [name ...]
 export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilrtux] [-p] name[=va>
 false                                   ulimit [-SHacdefilmnpqrstuvx] [limit>
 fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
 fg [job_spec]                           unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [name ...]
 for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
 function name { COMMANDS ; } or name >  variables - Names and meanings of so>
 getopts optstring name [arg]            wait [id]
 hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
 help [-dms] [pattern ...]               { COMMANDS ; }

read就是其中一个builtin命令,help也是,可以通过type查看命令是系统命令还是shell内置命令,type后面的参数如果是builtin命令,则type xxxx会传输xxxxis sell builtin。如果 type后面的参数不是built命令,则type xxxx输出xxxx is xxxx,如果系统中既有builtin命令也有同名的系统命令。则需要通过指定全路径的方式执行type命令。

type read
read is a shell builtin

which read
/usr/bin/read

type /usr/bin/read
/usr/bin/read is /usr/bin/read

file /usr/bin/read
/usr/bin/read: POSIX shell script, ASCII text executable

type echo
echo is a shell builtin

which echo
/usr/bin/echo

type /usr/bin/echo
/usr/bin/echo is /usr/bin/echo

file /usr/bin/echo
/usr/bin/echo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
dynamically linked (uses shared libs), for GNU/Linux 2.6.32, 
BuildID[sha1]=c2ff2c386aeffcf4352d7c20b07920d4286d7db6, stripped

通过如上测试,直接执行type的时候,shell会从内置命令中查找,除非指定命令的绝对路径。echo命令是内置命令,/usr/bin/echo和/usr/bin/read不一样,/usr/bin/echo是二进制程序,/usr/bin/read是可执行脚本。

type命令针对内置命令和系统命令做了识别,并且输出不一样,可以通过输出区分。

Shell 内部实现了很多 builtin 的命令,其主要目的就是为了提高 shell 命令的执行效率。不同 Shell 程序实现的 builtin 命令集各不相同。为了详细了解你当前使用的 Shell 所支持的 builtin 命令,需要查看 man 手册。譬如对于我们常用的 bash,运行 man bash 后搜索 “SHELL BUILTIN COMMANDS” 关键字会有专门的章节介绍 bash 所支持的 builtin 命令。如果我们只是想快速地列出所有 bash 支持的 builtin 命令,也可以在 bash 中执行 help 命令,这个命令本身就是一个 builtin 命令。如果是想查看具体的某个 builtin 命令的使用,可以带上 -m 参数,如下:

help -m echo
NAME
    echo - Write arguments to the standard output.

SYNOPSIS
    echo [-neE] [arg ...]

DESCRIPTION
    Write arguments to the standard output.
    
    Display the ARGs on the standard output followed by a newline.
    
    Options:
      -n	do not append a newline
      -e	enable interpretation of the following backslash escapes
      -E	explicitly suppress interpretation of backslash escapes
    
    `echo' interprets the following backslash-escaped characters:
      \a	alert (bell)
      \b	backspace
      \c	suppress further output
      \e	escape character
      \f	form feed
      \n	new line
      \r	carriage return
      \t	horizontal tab
      \v	vertical tab
      \\	backslash
      \0nnn	the character whose ASCII code is NNN (octal).  NNN can be
    	0 to 3 octal digits
      \xHH	the eight-bit character whose value is HH (hexadecimal).  HH
    	can be one or two hex digits
    
    Exit Status:
    Returns success unless a write error occurs.

SEE ALSO
    bash(1)

IMPLEMENTATION
    GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
    Copyright (C) 2011 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

由于各种 Shell 所支持的 builtin 命令各不相同,对于有些常用的命令,为避免用户当前所使用的 Shell 不支持,系统会提供同名的程序文件。譬如 echo,既是 bash 的 builtin 命令也是一个独立的命令程序。根据 bash 中执行命令的优先级,对于同名的命令,内置命令会优先被执行,所以当我们在 bash 中直接输入 echo 命令时执行的是 bash 的 buildin 命令,如果要执行独立的命令程序 echo,则需要输入全路径 /usr/bin/echo。

如果想要快速确定一个命令究竟是 bash 的 builtin 命令还是一个普通的程序命令,可以使用 type 命令进行检测。

平常脚本中执行的命令,多是builtin命令。系统中也会为了兼容脚本的执行,弥补文件的缺失,所以系统中多半会了兼容脚本的运行,创建出同名同功能的二进制程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值