Linux 环境变量
最近阅读了一些linux
相关的书籍、文章以及文档,想结合自己的理解来讲解一下linux
的环境变量。
本文的参考内容如下,感兴趣的小伙伴也可以阅读原文:
- linux man page online: 查询 linux 命令
- book: The Linux Command Line(11 - The Environment)
- Variables
我的日常开发环境如下:
- 操作系统:macos
shell
: zsh
变量
linux
中的变量有如下俩类:
shell
变量(局部变量): 只能在当前shell
中使用- 环境变量(全局变量): 可以传递变量到子
shell
可以通过以下俩种方式来查看定义的变量:
- printenv : 没有参数时列出所有的环境变量,有参数时列出参数对应的环境变量
- echo: 显示对应的
shell
变量或环境变量
shell
变量
在终端中可以直接通过name=value
的形式来创建变量:
# 等号左右俩边不能有空格
name=value
可以通过echo $<variable name>
来查看刚才定义的变量:
echo $name
# value
printenv <variable name>
可以查看定义的环境变量:
# 由于name不是环境变量,输出内容为空
printenv name
通过这种方式定义的变量只能在当前进程中使用,而无法在子进程中使用。
为了验证上述文字,使用bash
命令在终端中再创建一个子进程,可以看到,此时再次执行echo $name
不会输出任何内容:
➜ ~ bash
bash-3.2$ echo $name
bash-3.2$
环境变量
想要让变量能在子进程中也使用,需要通过export
来定义变量:
export name1=value1
查看定义的环境变量:
➜ ~ printenv name1
value1
➜ ~ echo $name1
value1
此时,我们在子进程中也能访问到定义的变量:
bash
bash-3.2$ printenv name1
value1
bash-3.2$ echo $name1
value1
但是当重新开启一个终端后,shell
变量和环境变量都会失效无法访问。为了能让变量永久的在所有终端中生效,需要修改配置文件
,这个会在之后进行详细介绍。
内置环境变量
操作系统中有许多内置的环境变量,执行printenv
可以查看这些变量:
# some environment variables
TERM_SESSION_ID=w0t0p0:D35D538F-01B7-407D-AC61-476CD68AE6E7
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.1Goz8bCjVc/Listeners
LC_TERMINAL_VERSION=3.4.16
COLORFGBG=7;0
ITERM_PROFILE=Default
XPC_FLAGS=0x0
SHELL=/bin/zsh
__CFBundleIdentifier=com.googlecode.iterm2
LC_CTYPE=UTF-8
TERM_PROGRAM_VERSION=3.4.16
TERM_PROGRAM=iTerm.app
LC_TERMINAL=iTerm2
COLORTERM=truecolor
COMMAND_MODE=unix2003
PATH=/Users/username/Library/pnpm:/Users/username/.bun/bin:/Users/username/.nvm/versions/node/v16.14.2/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/username/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/username/.yarn/bin
需要注意的是PATH
变量,PATH
中定义了由:
分割的目录列表,当用户在终端执行一个命令如ls
时,会在PATH
中定义的目录下进行查找,找到对应的文件然后执行。
作为前端开发者,以我们经常用到的npm
为例:
可以看到npm
所在目录存在于PATH
对应的目录列表中,所以我们才可以通过终端来执行npm
命令。其它的终端中的可执行命令,也是如此。
Node.js
中的环境变量(wait approve)
在Node.js
中可以通过process.env
来访问以及修改环境变量:
// 访问环境变量
console.log('mock', process.env.MOCK)
// 设置环境变量
process.env.MOCK = '22222'
需要注意的是,Node.js
在创建子进程的时候环境变量默认和父进程相同:
import { spawn } from 'node:child_process'
console.log('mock', process.env.MOCK)
process.env.MOCK = '22222'
const childProcess = spawn('sh', ['-c', 'echo $MOCK'], { stdio: 'inherit' })
childProcess.on('error', (err) => {
console.error(err)
})
执行上述代码MOCK=true npx tsx index.ts
,输出如下:
mock true
22222
Shell 初始化文件
当我们每次打开终端后,shell
便会从初始化文件中读取一系列配置,如环境变量、别名等。常见的shell
初始化文件如下:
文件 | 内容 |
---|---|
/etc/profile | 应用到所有用户的全局配置 |
/etc/bashrc | 应用到所有用户的全局配置(专用于bash ) |
~/.zshrc | 用户个人的zsh 配置 |
通过cat ~/.zshrc
命令,可以查看配置文件中的内容。下面展示的是我电脑中配置文件里的一些代码:
# If you come from bash you might have to change your $PATH.
export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"
alias cat="pygmentize -g"
可以看到,在配置文件中可以进行设置环境变量、设置别名等一系列操作。
修改配置文件
当然,配置文件也可以修改来实现一些用户自定义的内容。我们可以通过vim
命令,在命令行中直接修改配置文件
vim ~/.zshrc
比如,我们在配置文件中增加一个新的环境变量
# ... some other code
export A=test
需要注意的是,这样添加的内容只会在下次重新启动终端,再次读取配置文件时才会生效。为了让配置立即生效,要记得执行如下命令:
source ~/.zshrc
# 或者 . ~/.zshrc, 俩者作用完全相同
执行printenv A
来查看是否成功添加环境变量:
npm
执行scripts
中的cli
命令
以vite
为例,在启动项目时需要在package.json
的scripts
中配置{dev: "vite"}
命令,然后在终端执行npm run dev
,npm
便会执行scripts
中dev
对应的vite
命令。
而vite
命令在执行时,Node.js
会将其环境变量PATH
设置为node_modules/.bin
,即会在node_modules/.bin
中查找可以执行的vite
文件。其实现代码如下:
// npm-run-dev.ts
import { spawn } from 'node:child_process'
import { fileURLToPath } from 'node:url'
import process from 'node:process'
import path from 'node:path'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
// 核心:通过spawn执行 sh -c -- vite 命令,并将根目录下的./node_modules/.bin添加到环境变量中
// PATH和cwd要根据自已的目录结构来决定
const PATH = `${path.resolve(__dirname, '../../../', './node_modules/.bin')}:${
process.env.PATH
}`
const ls = spawn('sh', ['-c', '--', 'vite'], {
env: { PATH },
cwd: path.resolve(__dirname, '../../../playground/vue-jsx'),
stdio: 'inherit'
})
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`)
})
ls.on('error', (err) => {
console.log('err', err)
})
上述代码其实就是通过spawn
命令中的env
来指定命令执行时的环境变量,从而能够直接运行本地安装的cli
。最终node_modules/.bin/vite
在执行时,执行真正的vite
源代码。
使用tsx
执行上述代码,便可以实现与npm run dev
一样的效果。
结语
以下是文中涉及到的linux
命令:
学习linux
的相关知识,帮助我进一步深入理解了Node.js
中cli
的运行和调试过程,也让自己能更熟练的使用前端以及开发cli
工具。
以上就是我对linux
环境变量的一些理解,希望这些知识也能对你有所帮助。
转载自:https://juejin.cn/post/7162788361328361502