shell基础

什么是shell

  • 解释执行用户输入的命令或程序。
  • 用户输入一条命令,shell就解释一条。
  • 键盘输入命令,Linux给与响应的方式,称之为交互。

Shell是一块包裹着系统核心的壳,处于操作系统的最外层,与用户直接对话,把用户的输入解释给操作系统,然后处理操作系统的输出结果,输出到屏幕给用户。

shebang

计算机程序中,shebang指的是出现在文本第一行前两个字符#!

在Uninx系统中,程序会分析shebang后面的内容,作为解释器的指令,例如:

  • #! /bin/sh 开头的文件,程序在执行的时候,会调用/bin/sh,也就是bash去执行。
  • #! /usr/bin/python开头的文件,代表指定python解释器去执行。
  • #! /usr/bin/env开头的文件,是一种在不同平台都能正确找到解释器的办法。

注意事项:

  • 如果脚本未指定shebang,脚本执行的时候,默认用当前shell去解释脚本,即$SHELL
  • 如果shebang指定了可执行的解释器,如/bin/bash /usr/bin/python,脚本在执行的时候,文件名会作为参数传递给解释器。
  • 如果#!指定的解释程序没有可执行权限,则会报错bad interpreter; Permission denied
  • 如果#!指定的解释程序不是一个可执行的文件,那么指定的解释程序会被忽略,转而交给当前的$SHELL去执行这个脚本。
  • 如果#!指定的解释程序不存在,那么会报错bad interpreter: No such file or direcrory
  • #!之后的解释程序,需要写其绝对路径(如 #! /bin/bash),它是不会自动到$PATH中寻找解释器的。
  • 如果你使用bash test.sh 这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是命令行中显示指定的bash

脚本案例:

1
2
3
#! /usr/bin/python
# coding:utf-8
print('hello world')

脚本注释,脚本开发规范

shell脚本中,#后面的内容代表注释掉的内容,提供给开发者或者使用者查看,系统会忽略此行。

注释可以单独写一行,也可以跟在命令后面。

尽量保持爱写注释的习惯,便于以后回顾代码的含义,尽量使用英文,而非中文。

执行shell脚本的方式

  1. Bash scriptse.shsh scripte.sh,文件本身没有执行权限,没x权限,则使用的方法,或脚本没有指定shebang,重点推荐的方式。
  2. 使用绝对/相对路径来执行脚本,需要文件含有x权限。
  3. source script.sh 或者 . script.sh,代表执行的含义,source等于.
  4. 少见的用法, sh < script.sh 。(输入重定向)

shell和运维的关系

shell脚本语言很适合处理纯文本类型数据,且Linux的哲学思想就是一切皆文件,如日志、配置文件、文本、网页文件,大多数都是纯文本类型的,因此shell可以方便的进行文本处理,好比强大的Linux三剑客(grepsedawk)。

脚本语言

shell脚本语言属于一种弱类型语言,无需声明变量类型,直接定义使用。

查看系统支持的shell情况:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

查看当前默认使用的shell:

1
2
$ echo $SHELL
/bin/bash

bash

  • bash 是一个命令处理器,运行在文本窗口中,并能执行用户直接输入的命令
  • bash 还能从文件中读取linux命令,称之为脚本。
  • bash 支持通配符、管道、命令替换、条件判断等逻辑控制语句。

bash有诸多方便的功能,有助于运维人员提升工作效率。

命令历史

shell会保留其回话中用户提交执行的命令

1
2
3
4
5
6
$ echo $HISTSIZE # 查看 history 的数量
$ echo $HISTFILE # 查看 history 存放的文件
$ history -c # 清空 history
$ history -r filepath # 恢复 指定的文件的历史命令
$ !historyID # 快速执行指定历史命令
$ !! # 执行上一次命令

特性汇总

  • 文件路径tab键补全
  • 命令补全
  • 快捷键crtl + a,e,u,k,l
  • 通配符
  • 历史命令
  • 命令别名
  • 命令行展开

shell变量

  • 变量定义与赋值,注意变量与值之间不得有空格。
1
2
$ name='hello world' # good
$ name = 'hello world' # bad
  • bash变量默认都是字符串类型的。是一个弱类型语言。
  • 变量引用
1
2
3
name='hello world'
echo $name # 简写
echo ${name} # 规范写法
  • 变量名规则

    • 名称定义要做到见名知意,切按照规则来,切不得引用保留关键字
    • 只能包含数字、字母、下划线
    • 不能以数字开头
    • 不能用标点符号
    • 变量名严格区分大小写
  • 变量名的作用域

    • 本地变量,只针对当前的shell进程。
    • 环境变量,也称为全局变量,针对当前shell以及其任意子进程,环境变量也分为自定义、内置两种环境变量。
    • 局部变量,针对在shell函数或是shell脚本中定义。
  • 位置参数变量,用于shell脚本中传递的参数。

  • 特殊变量:shell内置的特殊功效变量。

    • $?
      • 0::成功
      • 1-255:错误码
  • 自定义变量

    • 变量赋值:varname=value

    • 变量引用:${varname}、$varname

    • 单引号不能识别变量,双引号可以识别变量。

      1
      2
      3
      4
      5
      6
      7
      8
      ~ ❯ name='h'
      ~ ❯ name2='e'
      ~ ❯ name3="$name"
      ~ ❯ echo ${name3}
      h
      ~ ❯ name4='$name2'
      ~ ❯ echo ${name4}
      $name2

注意:

  1. 每次调用bash都会开启一个子shell,因此不保留当前的shell变量。
  2. 调用source是在当前shell环境加载脚本,因此保留变量。
1
2
3
4
5
6
7
8
9
10
11
root@VM-12-2-ubuntu:~# cat t.sh
#! /bin/bash
name="Ezreal"
root@VM-12-2-ubuntu:~# name="Jun"
root@VM-12-2-ubuntu:~# bash t.sh
root@VM-12-2-ubuntu:~# echo $name
Jun
root@VM-12-2-ubuntu:~# . ./t.sh
root@VM-12-2-ubuntu:~# echo $name
Ezreal
root@VM-12-2-ubuntu:~#

环境变量设置

环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。

shell通过环境变量确定登陆的用户名、path 路径、文件系统等各种应用。

环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件。

  • 用户个人配置文件 ~/.bash_profile ~/.bashrc 远程登陆用户特有文件。
  • 全局配置文件/etc/profile /etc/bashrc,且系统建议最好创建在/etc/profile.d/,而非直接改主文件,修改全局配置文件,影响所有登陆系统的用户。

检查系统环境变量的命令:

  • set,输出所有变量,包括全局变量,局部变量。
  • env,只显示全局变量。
  • export,显示和设置环境变量值。

撤销环境变量

  • unset 变量名,删除变量或函数。

设置只读变量

  • readonly,只有shell结束,只读变量才会失效。

    1
    2
    3
    root@VM-12-2-ubuntu:~# readonly name='h'
    root@VM-12-2-ubuntu:~# name='e'
    bash: name: readonly variable

系统保留环境变量关键字

bash内嵌了诸多环境变量,用于定义bash的工作环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$ ~ ❯ export | awk -F '[ :=]' '{print $1}' # 获取变量名称 Macos系统
COLORFGBG
COLORTERM
COMMAND_MODE
GOPATH
GOPRIVATE
GOROOT
HOME
HOMEBREW_NO_AUTO_UPDATE
ITERM_PROFILE
ITERM_SESSION_ID
LANG
LC_TERMINAL
LC_TERMINAL_VERSION
LESS
LOGNAME
LSCOLORS
NVM_BIN
NVM_CD_FLAGS
NVM_DIR
NVM_INC
NVM_RC_VERSION
OLDPWD
P9K_SSH
P9K_TTY
PAGER
PATH
PWD
PYENV_ROOT
PYENV_SHELL
SHELL
SHLVL
SSH_AUTH_SOCK
TERM
TERM_PROGRAM
TERM_PROGRAM_VERSION
TERM_SESSION_ID
TMPDIR
USER
XPC_FLAGS
XPC_SERVICE_NAME
ZSH
_P9K_TTY
__CFBundleIdentifier
__CF_USER_TEXT_ENCODING
~ ❯

shell加载顺序

shell 加载顺序

shell特殊参数变量

shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量

  • $0 获取shell脚本文件名,以及脚本路径
  • $n 获取shell脚本的第n个参数,n在1-9之间,如$1,$2,$9,大于9则需要写,${10},参数空格隔开。
  • $# 获取执行的shell脚本后面的参数总个数
  • $* 获取shell脚本所有参数,不加引号等同于$@作用,加上引号”$*”作用是接受所有参数为单个字符串,”$1 $2 $3…”
  • $@ 不加引号,效果如$*,加引号,是接受所有参数为独立字符串,如”$1” “$2” “$3” … 空格保留。

实战:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#! /bin/bash
echo '特殊变量 $0 $1 $2 ...的实战'
echo '结果:' $0 $1 $2

echo '##############################'
echo '----特殊变量$# 获取参数的总个数'
echo '结果:' $#

echo '##############################'
echo '---特殊变量$* 实战'
echo '结果:' $*


echo '##############################'
echo '---特殊变量$@ 实战'
echo '结果:' $@

$* 和 $@ 在不加引号的区别没有任何区别。$@加引号后,就是单个字符串。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
#! /bin/bash
echo "print each param form \"$*\""
for var in "$*"
do
echo "$var"
done

echo "print each param form \"$@\""
for var in "$@"
do
echo "$var"
done

运行结果:

1
2
3
4
5
6
7
8
root@VM-12-2-ubuntu:~# bash t.sh a b c d
print each param form "a b c d"
a b c d
print each param form "a b c d"
a
b
c
d

shell特殊状态变量

  • $? 获取上一次命令执行状态返回值,0正确,非0失败
  • $$ 获取当前shell脚本的进程号
  • $! 获取上一次后台进程的pid
  • $_ 获取上次执行的命令的最后一个参数

示例:

1
2
3
4
5
6
#! /bin/bash
[ $# -ne 2 ] && {
echo "must be two args"
exit 119 # 终止程序运行
}
echo ok

内置shell命令

  • echo

    • -n 不换行

    • -e 解析字符串中的特殊符号

    • \n 换行

    • \r 回车

    • \t 制表符

    • -b 退格

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      ~ ❯ echo a; echo b;
      a
      b
      ~ ❯ echo -n a; echo b;
      ab
      root@VM-12-2-ubuntu:~# echo "a\nb"
      a\nb
      root@VM-12-2-ubuntu:~# echo -e "a\nb"
      a
      b
  • eval 执行多个命令

    1
    2
    3
    root@VM-12-2-ubuntu:~# eval ls;cd /var
    prometheus.sh restart.sh shelltest t.sh
    root@VM-12-2-ubuntu:/var#
  • exec 不创建子进程执行后续命令,且执行完毕后,自动exit。

shell子串用法

1
2
3
4
5
6
7
8
9
10
${变量} 							返回变量值
${#变量} 返回变量长度,字符长度
${变量:start} 返回变量start数值之后的字符,且包含start
${变量:start:length} 提取start之后的length限制的字符,且包含start
${变量#word} 从变量开头删除最短匹配的word子串
${变量##word} 从变量开头,删除最长匹配的word
${变量%word} 从变量结尾处删除最短的word
${变量%%word} 从变量结尾开始删除最长匹配的word
${变量/pattern/string} 用string代替第一个匹配的pattern
${变量//pattern/strig} 用string代替所有的pattern

shell 变量截取字符串通常有两种方式:

  1. 从指定位置开始截取。
  2. 从指定字符(子字符串)开始截取。
1
2
3
4
5
6
7
8
9
10
11
12
13
root@VM-12-2-ubuntu:~# name='helloworld'
root@VM-12-2-ubuntu:~# echo ${name} #输出字符串
helloworld
root@VM-12-2-ubuntu:~# echo ${#name} # 统计字符串长度
10
root@VM-12-2-ubuntu:~# echo ${name:3} # 从索引3开始截取
loworld
root@VM-12-2-ubuntu:~# echo ${name:3:2} # 从索引3开始截取,长度为2
lo
root@VM-12-2-ubuntu:~# echo ${name} | wc -l # 统计行数
1
root@VM-12-2-ubuntu:~# echo ${name} | wc -L # 统计最长的一行的字数
10

shell统计字符串的长度

1
2
3
4
1. ${#变量} (速度最快!!)
2. wc -L
3. expr length ${变量}
4. awk

演示:

1
2
3
4
5
6
7
8
9
10
root@VM-12-2-ubuntu:~# echo $name
helloworld
root@VM-12-2-ubuntu:~# expr length ${name}
10
root@VM-12-2-ubuntu:~# echo $name | awk '{print length($0)}'
10
root@VM-12-2-ubuntu:~# echo ${#name}
10
root@VM-12-2-ubuntu:~# echo ${name} | wc -L
10

速度比较:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@VM-12-2-ubuntu:~# time for n in {1...100000};do char=`seq -s "helloworld" 10000`;echo ${#char} &> /dev/null;done

real 0m0.009s
user 0m0.010s
sys 0m0.000s
root@VM-12-2-ubuntu:~# time for n in {1...100000};do char=`seq -s "helloworld" 10000`;echo ${char} | wc -L &> /dev/null;done

real 0m0.015s
user 0m0.017s
sys 0m0.000s
root@VM-12-2-ubuntu:~# time for n in {1...100000};do char=`seq -s "helloworld" 10000`;expr length ${char} &> /dev/null;done

real 0m0.013s
user 0m0.007s
sys 0m0.008s
root@VM-12-2-ubuntu:~# time for n in {1...100000};do char=`seq -s "helloworld" 10000`;echo ${char} | awk '{print length($0)}' &> /dev/null;done

real 0m0.014s
user 0m0.012s
sys 0m0.006s

shell编程,尽量使用内置命令

字符串截取和替换

# 指定字符内容截取

a*c 匹配开头为a,中间任意个字符,结尾为c的字符串

a*C 匹配开头为a,中间任意个字符,结尾为C的字符串

示例:

1
2
3
4
5
root@VM-12-2-ubuntu:~# name='abc123abc123abcABC'
root@VM-12-2-ubuntu:~# echo ${name#a*c}
123abc123abcABC
root@VM-12-2-ubuntu:~# echo ${name##a*c}
ABC

批量删除文件名

准备工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@VM-12-2-ubuntu:/var/opt# touch ezreal_{1..5}_hello.jpg
root@VM-12-2-ubuntu:/var/opt# touch ezreal_{1..5}_hello.png
root@VM-12-2-ubuntu:/var/opt# ll
total 8
drwxr-xr-x 2 root root 4096 Apr 30 18:16 ./
drwxr-xr-x 15 root root 4096 Mar 12 20:38 ../
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_1_hello.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_1_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_2_hello.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_2_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_3_hello.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_3_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_4_hello.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_4_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_5_hello.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_5_hello.png

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@VM-12-2-ubuntu:/var/opt# for file_name in `ls *hello*jpg`;do mv ${file_name} `echo ${file_name//_hello/}`; done
root@VM-12-2-ubuntu:/var/opt# ll
total 8
drwxr-xr-x 2 root root 4096 Apr 30 19:09 ./
drwxr-xr-x 15 root root 4096 Mar 12 20:38 ../
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_1_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_1.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_2_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_2.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_3_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_3.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_4_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_4.jpg
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_5_hello.png
-rw-r--r-- 1 root root 0 Apr 30 18:16 ezreal_5.jpg
root@VM-12-2-ubuntu:/var/opt#

特殊shell扩展变量

下面四个语法都是对变量的值进行判断、处理。

1
2
3
4
5
6
7
8
9
10
11
${parameter:-word}
如果parameter变量为空,返回word字符串

${parameter:=word}
如果parameter变量为空,则word替代变量值,且返回其值

${parameter:?word}
如果parameter变量为空,word当做stderr输出,否则输出变量值,用于设置变量为空导致错误时,返回的错误信息。

${parameter:+word}
如果parameter为空,什么都不做,否则word返回

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@VM-12-2-ubuntu:~# echo ${name}

root@VM-12-2-ubuntu:~# echo ${name:-word}
word
root@VM-12-2-ubuntu:~# echo ${name:=word}
word
root@VM-12-2-ubuntu:~# echo $name
word
root@VM-12-2-ubuntu:~# echo $h

root@VM-12-2-ubuntu:~# echo ${h:?word}
-bash: h: word
root@VM-12-2-ubuntu:~# echo ${h:?不存在h变量}
-bash: h: 不存在h变量
root@VM-12-2-ubuntu:~# echo ${h:+word}

root@VM-12-2-ubuntu:~# echo ${name:+word}
word
root@VM-12-2-ubuntu:~#

父子shell

父子 shell

  1. source和.,执行脚本,只在当前的shell环境中执行生效。
  2. 指定bash sh 解释运行脚本,是开启subshell,开启子shell运行脚本命令。
  3. ./script,都会指定shebang,通过解释器运行,也是开启subshell运行命令。

查看:

1
2
3
4
5
root@VM-12-2-ubuntu:~# ps -ef --forest | grep php | grep -v grep 
root 27343 1 0 Mar27 ? 00:01:29 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)
www 29232 27343 0 Apr28 ? 00:00:24 \_ php-fpm: pool www
www 21658 27343 0 08:32 ? 00:00:03 \_ php-fpm: pool www
www 21659 27343 0 08:32 ? 00:00:02 \_ php-fpm: pool www

父子 shell

检测是否在shell环境中

linux默认的有关shell的变量

BASH_SUBSHELL

该变量值的特点,如果是0,就是在当前shell环境中执行,否则就是开启了子shell运行的。

如果执行命令用()包裹,就是一个子shell列表。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
root@VM-12-2-ubuntu:~# cd; pwd; ll; echo $BASH_SUBSHELL;
/root
total 152
drwx------ 10 root root 4096 Apr 30 14:53 ./
drwxr-xr-x 24 root root 4096 Apr 30 22:33 ../
-rw------- 1 root root 50730 Apr 30 22:22 .bash_history
-rw-r--r-- 1 ubuntu ubuntu 3276 Apr 29 15:29 .bashrc
......
0 # 代表是在当前shell运行的。
root@VM-12-2-ubuntu:~# (cd; pwd; echo $BASH_SUBSHELL)
/root
1 # 表示在第一层子shell中
root@VM-12-2-ubuntu:~# (cd; pwd;(cd /opt; (ll; echo $BASH_SUBSHELL)))/root
total 76
drwxr-xr-x 18 root root 4096 Apr 24 19:15 ./
drwxr-xr-x 24 root root 4096 Apr 30 22:35 ../
drwx--x--x 4 root root 4096 Mar 8 10:11 containerd/
drwxr-xr-x 7 root root 4096 Apr 11 22:06 filebeat-7.5.2/
drwxr-xr-x 5 root root 4096 Apr 12 20:45 go/
drwxr-xr-x 8 root root 4096 Mar 27 19:31 grafana-8.4.2/
drwxr-xr-x 8 root root 4096 Apr 11 20:41 kafka_2.12-3.1.0/
drwxr-xr-x 3 root root 4096 Jan 11 23:23 knem-1.1.4.90mlnx1/
drwxr-xr-x 7 root root 4096 Jan 11 23:23 mellanox/
drwxr-xr-x 2 3434 3434 4096 Mar 27 17:51 mysqld_exporter-0.14.0/
drwxr-xr-x 4 root root 4096 Jan 11 23:23 neohost/
drwxr-xr-x 2 3434 3434 4096 Mar 27 17:50 node_exporter-1.3.1/
drwxrwxr-x 3 root root 4096 Mar 27 20:53 php-fpm-exporter-0.6.1/
drwxr-xr-x 5 3434 3434 4096 Apr 11 18:05 prometheus-2.33.4/
drwxr-xr-x 2 3434 3434 4096 Mar 27 17:49 pushgateway-1.4.2/
drwxr-xr-x 5 root root 4096 Mar 8 10:16 ql/
drwxr-xr-x 2 3434 3434 4096 Apr 11 18:20 thanos-0.25.2/
-rw-r--r-- 1 root root 1532 Apr 24 19:21 wget-log
drwxr-xr-x 4 www www 4096 Apr 30 14:54 www/
3 # 表示在第三层shell中

利用括号,开始子shell的理念,以及检查,在shell脚本开发中,经常会用子shell进行多进程的处理,来提高程序并发执行的效率。

内置命令、外置命令

通过type 可以查看是内置还是外置命令。

内置命令

在系统启动时就加入内存,常驻内存,执行效率更高,但是占用资源。

内置命令不会产生子进程去执行,是和shell为一体的,是shell的一部分,不需要单独去读取某个文件,系统启动后,就常驻在内存中了。

1
2
root@VM-12-2-ubuntu:~# type cd
cd is a shell builtin # cd 是内置命令

查看有哪些内置命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
root@VM-12-2-ubuntu:~# compgen -b
.
:
[
alias
bg
bind
break
builtin
caller
cd
command
compgen
complete
compopt
continue
declare
dirs
disown
echo
enable
eval
exec
exit
export
false
fc
fg
getopts
hash
help
history
jobs
kill
let
local
logout
mapfile
popd
printf
pushd
pwd
read
readarray
readonly
return
set
shift
shopt
source
suspend
test
times
trap
true
type
typeset
ulimit
umask
unalias
unset
wait

外置命令

用户需要从硬盘中读取程序文件,在读入内存加载。也称之为自己单独下载的文件系统命令,处于bash shell 之外的程序。外置命令的特点是:一定会开启子进程执行。

1
2
3
4
root@VM-12-2-ubuntu:~# type nginx
nginx is /usr/sbin/nginx
root@VM-12-2-ubuntu:~# type ps
ps is /bin/ps

其关系如下:

外置命令


shell基础
https://randzz.cn/c68c0194a4f7/shell基础/
作者
Ezreal Rao
发布于
2022年4月30日
许可协议