zsh

zsh命令

符号 作用 示例 执行逻辑
; 顺序执行,无论前一条命令是否成功 cmd1; cmd2 执行 cmd1,然后执行 cmd2
&& 仅当前一条命令成功(退出状态码为 0)时,才执行下一条命令 cmd1 && cmd2 若 cmd1 成功,则执行 cmd2
` ` 仅当前一条命令失败(退出状态码非 0)时,才执行下一条命令
& 前一条命令在后台运行,不阻塞下一条命令 cmd1 & cmd2 cmd1 后台运行,同时执行 cmd2
` ` 仅当前一条命令失败(退出状态码大于0)时,才执行下一条命令
单引号 包裹的内容原样输出,不展开变量、命令、通配符、转义 echo '$HOME' 输出 $HOME 直接原样输出所有包裹在单引号内部的内容
双引号 展开变量、命令、通配符、转义,其余内容原样输出 echo '$HOME' 输出 /Users/roland 先在shell内将变量、命令、通配符、转义等展开,再传递给命令

Echo命令,控制台输出, \n参数用于去除末尾自动换行。

Source命令,接脚本文件,执行脚本,并且脚本中若定义了函数或者变量,都直接在当前shell中生效。 而如果执行输入脚本文件,相当于在新的shell子进程中运行脚本,不会影响当前shell环境。
. 是 source 的等效写法(例如 . ~/.zshrc)。

Export命令,用于使普通变量对当前shell的子进程也有效。
比如: v1=“hello”, 然后export v1
也可以 export v1=“hello”

执行任何外部命令都会在子进程中执行。

>>: 追加内容到文件末尾
: 代表用户的家目录
>> ~/.zshrc: 追加内容到文件末尾。 .zshrc是Zsh Shell的配置文件,每次启动终端(严格说是启动Zsh Shell)都会自动执行这个配置文件中的脚本。

cd: 进入某一层目录
当目标为符号链接时,跟随符号链接,进入到逻辑相同的目录。
cd -P 符号链接, 进入到实际的物理目录。
比如/opt/homebrew/opt目录下的python@3.13是一个符号链接,指向../Cellar/python@3.13/3.13.3
cd /opt/homebrew/opt/python@3.13 进入逻辑目录
此时pwd显示 /opt/homebrew/opt/python@3.13
Pwd -P 显示/opt/homebrew/Cellar/python@3.13/3.13.3

若使用cd -P opt/homebrew/opt/python@3.13, 则进入物理目录
此时pwdpwd -P 都显示 /opt/homebrew/Cellar/python@3.13/3.13.3

pwd: 显示当前目录

ls: 查看目录内容
ls [选项] [目录或文件]
-a: 显示隐藏文件
-l: 显示详细信息(列表样式)
-d: 只显示目录,不递归。
-p: 显示时会对目录名称后面加个“/”,便于区分是目录还是文件。

ls -d 等价于 ls -d . 因为目录或文件参数默认值是.
ls默认显示目录中所有内容(不包括隐藏文件) , 而所显示的目录如果不指定,就是当前目录,即“.”, 即 ls 等价于 ls .
-d选项是只显示目录,所有 ls -d 等价于 ls -d . 就只显示当前目录本身,所有就只显示一个 “.”。 当然这样是没有意义的。

目录或文件通配符:
*: 代表目录或文件
*/ : 代表目录
ls * 会显示当前目录的所有文件及子目录和子目录的所有文件
ls -d * 由于有-d选项,只保留了子目录部分,不会显示子目录里的文件

grep: 文本搜索工具
grep [选项] "搜索模式" [文件或目录]
* 搜索模式 :可以是普通字符串或正则表达式。
* 文件或目录 :如果省略,则从标准输入(如管道 |)读取数据。

Whichwhere 的区别:

特性 which where
搜索范围 第一个匹配项 所有匹配项
显示别名/函数 是(优先显示) 是(并列出所有路径)
递归搜索 $PATH
which python3
/opt/homebrew/bin/python3
Where python3
/opt/homebrew/bin/python3
/usr/bin/python3

读取符号链接的真实路径

readlink -f mylink
realpath mylink

file [选项] 文件名或路径
检测文件类型。

复杂命令拆解:
dirname "$(readlink -f "$(which python3)”)”
$(command): 命令替换, 等价于将括号中的命令的输出会存到一个变量中,之后再引用这个变量。
双引号作用: 防止返回的内容(尤其是路径)中有空格,影响其做为一个整体做为下一个命令的参数。

dirname: 返回上级目录
basename: 返回最末级目录或文件

环境变量配置文件

配置文件 加载时机与场景 核心用途 典型配置内容
~/.zprofile 登录 Shell(如系统首次启动终端、SSH登录)时加载一次 设置全局环境变量和只需初始化一次的配置。 PATH, JAVA_HOME, HOMEBREW_API_DOMAIN 等环境变量;执行 eval "$(brew shellenv)"
~/.zshrc 交互式 Shell(每次打开新的终端窗口或标签页)时加载。 定义交互式功能,提升命令行体验。 命令别名(alias)、提示符主题、自动补全插件等。
~/.bash_profile 适用于 Bash Shell 的登录配置,与 ~/.zprofile 在 Zsh 中的角色类似。 在 Bash 中设置环境变量。 如果你使用 Bash(macOS 较新版本默认是 Zsh),环境变量应放在此文件中。

查看所有环境变量
env或者printenv

在当前shell环境中删除环境变量,但不会永久修改环境变量。因为环境变量可能是在配置文件中,下载启动shell还会再加载。

unset HOMEBREW_BOTTLE_DOMAIN
unset HOMEBREW_API_DOMAIN

.DS_Store:全名:Desktop Services Store)是 macOS Finder 自动生成的隐藏文件。
它存在于每一个被 Finder 打开过的文件夹中。
作用是保存该文件夹的 自定义视图设置,比如:

  • 图标位置
  • 排序方式
  • 背景图片
  • 列宽、图标大小等

_MACOSX 文件夹,是 macOS 系统在使用 归档工具(Archive Utility) 压缩文件夹时自动生成的一个隐藏目录。它的作用是保存一些 macOS 特有的元数据信息,比如:

  • 资源派生(Resource forks)
  • 扩展属性(Extended attributes)
  • Finder 信息(如图标位置、标签颜色等)
  • 文件权限和创建时间等

文件压缩
如果直接在访达里使用右击文件夹的方式,会在压缩包中产生_MACOSX这个文件夹,并且如果文件夹中有隐藏的.DS_Store文件存在,也会打包进压缩包里。 另外,这样打的包总是会存在顶层目录,名称默认为这个文件夹的名称。

这时应该用zip命令来进行压缩,以避免上述问题。
在目标文件夹外层时,用zip命令压缩时不可避免的要产生名为该目标文件夹的顶层目录。
zip -r archive.zip target_folder
将当前目录cd进目标文件夹内部时,可以避免将顶层目录打包进压缩包。 这时目标文件夹可以直接用“.”来表示
zip -r ../archive.zip .
-X 参数,用于避免在压缩包中产生_MACOSX文件夹
-x 参数,用于排除某些文件,比如.DS_Store文件, 此参数位置应该放在目标文件夹之后。
-r 参数,用于将目标文件夹中的所有层级的子目录也打包进压缩包
下面命令就排除了将_MACOSX文件夹和.DS_Store文件打包进压缩包的可能。实际上写的是"*.DS_Store",使用了通配符,这样可以避免子目录里的".DS_Store"文件被打进压缩包。
zip -r -X ../archive.zip . -x "*.DS_Store"

解压缩

unzip 压缩包文件 将压缩包解压到当前目录
unzip 压缩包文件 -d /your/path 将压缩包解压到指定目录, 其中最后一层目录如果不存在,可以自动创建,但如果其他层目录不存在,则会报错
unzip -l 压缩包文件 不解压,只为查看压缩包里的内容
unzip -Z1 压缩包文件 同上,只不过显示的压缩包内容只包含文件名称,不包含文件大小,创建时间等信息
unzip -j project.zip 扁平化解压,压缩包内各个层级文件夹里的文件都解压到同一个目录下,不保留原来目录层级。 如果出现同名文件,则后解压出来的文件会覆盖先解压出的同名文件。

🔍 Shell 执行一行命令的完整流程(简化版)

当你在终端输入:
zip -r out.zip .

Shell(如 bash/zsh)会按以下顺序处理:
步骤 1️⃣:解析(Parsing)

  • 按空格/制表符分词(word splitting)
  • 处理引号、转义、变量展开、通配符等
  • 得到一个参数列表(argv),例如:
[0] "zip"
[1] "-r"
[2] "out.zip"
[3] "."```
📌 此时 Shell 还不知道 zip 是否存在,只是把它当作“第一个 token”。

步骤 2️⃣:查找命令(Command Lookup)

Shell 按固定优先级顺序尝试解释第一个单词(zip):

优先级 类型 说明
1️⃣ 函数(Function) 当前 shell 中定义的函数
2️⃣ 内置命令(Builtin) 如 cd, echo, export(由 shell 自身实现)
3️⃣ 别名(Alias) 如 alias ll='ls -l'(注意:别名在解析早期就被展开了)
4️⃣ 可执行文件(External Command) 在 $PATH 环境变量列出的目录中搜索 zip

💡 这个顺序很重要!比如你定义了一个叫 cd 的函数,它会覆盖系统内置的 cd。

步骤 3️⃣:执行或报错

  • 如果在上述任一位置找到 → 执行它,并传入后续参数

  • 如果全部没找到 → 报错:

zsh: command not found: zip
bash: zip: command not found

📝 总结

|阶段| 行为|

|------| ------|
|1. 解析| 把命令行切成单词,处理引号、变量等|
|2. 查找| 按 函数 → 内置 → 别名 → PATH 顺序找第一个单词|
|3. 执行| 找到就执行 + 传参;找不到就报错|
✅ 所以准确说法是:
“Shell 将第一个单词视为‘命令名’,并按优先级顺序尝试解析它;如果所有方式都找不到,才报错‘command not found’。”

也是由于以上原因,在shell中输入 zip -rX archive.zip . -x "*.DS_Store" 的效果等同于"zip" "-rX" "archive.zip" "." "-x" "*.DS_Store"
所以,引号不是只能在路径之类的参数上加的,理论上,输出的内容里不含变量等内容,加不加引号其实是没影响的。

posted @ 2025-10-02 23:02  RolandHe  阅读(19)  评论(0)    收藏  举报