Skip to content
On this page

学习shell命令(二)

本文涉及知识点

  • shell命令基础
  • linux文件目录结构
  • npm install -g原理
  • 软链基础

概念

shell是用来提供用户与操作系统之间交互的容器,shell程序从脚本中一条条读取并执行。

shell命令是一种解释型脚本语言,无需编译,脚本语言通常不需要在使用变量之前声明其类型,只需要直接赋值就可以了。

shell命令的分类

命令分为2种,自带的命令可扩展的命令。在linux系统中,一切都是文件,可扩展的命令就是在文件夹下的文件。

我们说shell是一个容器,很明显,自带的命令随着shell的运行自动载入内存,而扩展的命令在运行时,shell会在PATH中搜索这条命令,如果能够找到,则fork子进程去处理。

如何区分自带的命令?

type cd
# cd is a shell builtin

type mmp
# mmp is /Users/yangming/.nvm/versions/node/v10.8.0/bin/mmp

type webpack
# webpack is /usr/local/bin/webpack

我们可以查看PATH来证实其中包含了扩展命令

echo $PATH

# /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/bin:
# /Users/yangming/.nvm/versions/node/v10.8.0/bin:
# /Users/yangming/.rvm/gems/ruby-2.0.0-p648/bin:
# /Users/yangming/.rvm/gems/ruby-2.0.0-p648@global/bin:
# /Users/yangming/.rvm/rubies/ruby-2.0.0-p648/bin:
# /usr/local/bin:
# /usr/bin:
# /bin:
# /usr/sbin:
# /sbin:
# /Users/yangming/.rvm/bin:
# /Users/yangming/.rvm/bin:
# .:
# /Users/yangming/mongodb/bin

环境变量的分割在mac里是:分割的。我们可以看到PATH中包含了webpack命令等。

命令目录

一般来讲/bin/sbin都是对/usr/bin/usr/sbin的符号链接,它们是相等的。

  • /usr/bin 进入后我们发现是系统自带的扩展命令,catcpls
  • /sbin 引导系统的命令,rebootmd5
  • /usr/sbin 也是系统级命令
  • /usr/local/bin 这是我们用户需要关心的目录,二进制/可执行程序的存储目录

使用type查看npm和webpack各自的可执行目录

npm is /Users/yangming/.nvm/versions/node/v10.8.0/bin/npm
webpack is /usr/local/bin/webpack

它们各自的实际目录分别为

/Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/npm
/usr/local/lib/node_modules/webpack

为什么会不一样?包括我自己npm i mmp-cli -g的工具也是和npm一样的目录

这个就涉及到npm install -g的原理步骤了,且让我们娓娓道来

npm install -g的原理

我们在创建可执行包时是这么定义的

js
"bin": {
  "mmp": "./bin/index"
}

当全局安装的时候

  • 会先给这个文件赋可执行权限chmod +x index.js
  • 然后创建软链 sudo ln -s /node/lib/node_modules/mmp/bin/index usr/local/bin/mmp

而之所以目录不一样是根据npm的prefix决定的,

# 查看全局的prefix
npm prefix -g 

# 设置prefix
npm config prefix /usr/local -g

# 查看全部的config
npm config ls -l

我们看一下cnpm全局安装的过程

Downloading mmp-cli to /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli_tmp

Copying /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli_tmp/_mmp-cli@1.0.24@mmp-cli to /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli

Installing mmp-cli's dependencies to /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli/node_modules
[1/8] colors@^1.3.2 installed at node_modules/_colors@1.3.2@colors
[2/8] app-root-path@^2.1.0 installed at node_modules/_app-root-path@2.1.0@app-root-path
[3/8] commander@^2.19.0 installed at node_modules/_commander@2.19.0@commander
[4/8] ora@^3.0.0 installed at node_modules/_ora@3.0.0@ora
[5/8] chalk@^2.4.1 installed at node_modules/_chalk@2.4.1@chalk
[6/8] boxen@^2.0.0 installed at node_modules/_boxen@2.0.0@boxen
[7/8] bluebird@^3.5.2 installed at node_modules/_bluebird@3.5.3@bluebird
[8/8] inquirer@^6.2.0 installed at node_modules/_inquirer@6.2.0@inquirer
Recently updated (since 2018-11-02): 1 packages (detail see file /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli/node_modules/.recently_updates.txt)
  2018-11-07
    → bluebird@^3.5.2(3.5.3) (04:06:22)
All packages installed (64 packages installed from npm registry, used 18s(network 18s), speed 115.71kB/s, json 64(243.53kB), tarball 1.8MB)

[mmp-cli@1.0.24] link /Users/yangming/.nvm/versions/node/v10.8.0/bin/mmp@ -> /Users/yangming/.nvm/versions/node/v10.8.0/lib/node_modules/mmp-cli/bin/index

可以很清晰的看到先下载再link

软链的创建与删除

# 创建
ln -s [file_path] [symbolic_name]

# 删除
rm -rf [symbolic_name]

当我们使用ll查看时

lrwxr-xr-x  1 yangming  admin    37B  1 19  2018 rollup -> ../lib/node_modules/rollup/bin/rollup

可以清晰的看到软链的指向

总结

我们之所以可以在shell的任意地方使用npm包,就是npm根据prefix下载相应文件后,创建软链并给定可执行权限,根据shell的扩展命令机制,会去搜索PATH里的可执行文件。

同理,其它的包管理器也应该是这个原理。


参考