1. 引言

日常开发中,Shell 脚本的使用非常广泛,无论是自动化构建、服务部署还是环境配置,都离不开 Bash/Zsh 等脚本。传统的 Shell 脚本调试方式多是靠 echo 打印变量或 set -x 输出执行过程,效率较低且不够直观。

VSCode 拥有非常优秀的扩展生态,配合适当的插件和配置,可以构建一个接近 IDE 级别的 Shell 脚本编写与调试环境。本文将系统讲解如何从零开始,在 VSCode 中搭建一个舒适高效的 Shell 开发与调试环境。

2. 基础软件与插件准备

2.1 推荐的基础软件

在 Linux/macOS 环境下直接使用系统自带的 Bash 或 Zsh 即可。对于 Windows 用户,推荐以下几种方案:

  • WSL2(推荐):安装 Windows Subsystem for Linux 2,获得完整的 Linux 发行版环境,VSCode 原生支持 WSL Remote 扩展,体验极佳。
  • Git Bash:Git for Windows 自带的 Bash 终端,可以部分模拟 Linux 命令行环境。
  • MSYS2 或 Cygwin:提供较完整的 POSIX 兼容环境及包管理工具。

为获得最佳调试体验,本文后续内容均以 WSL2 + Ubuntu 为例说明,macOS 与原生 Linux 环境配置步骤基本一致。

2.2 VSCode 必备插件

打开 VSCode 扩展商店,安装以下插件:

插件名称 用途说明
Bash IDE / Shell Script(由 madnessmany 开发) 代码智能提示、跳转定义、引用查找、语法检查等 IDE 功能,语法高亮、代码补全、代码格式化
shell-format 代码格式化,保持一致的缩进和换行风格
shellcheck(可选,需单独安装 ShellCheck 工具) 静态分析,检测脚本中的潜在陷阱、错误和不良写法
Shellman 提供丰富的 Shell 代码片段,快速插入常用脚本模板
Trailing Spaces(通用插件) 行尾多余空格高亮或自动删除,保持代码整洁
Remote - WSL 直接在 Linux 环境运行调试,环境最纯净, WSL 连接工具, VSCode 安装 WSL 扩展,点击左下角连接到 WSL,直接在 Ubuntu 环境里开发脚本,避免 Windows 换行符(CRLF)问题
Bash Debug :核心调试插件,支持断点调试 bash 脚本,作者:rogalmic
code runner :核心调试插件,支持断点调试 bash 脚本,作者:rogalmic

3. 环境初始化

3.1 在 WSL2 中安装开发工具

进入 WSL2 终端,执行以下命令安装必要组件:

sudo apt update
sudo apt install -y \
  bash \
  shellcheck \
  shfmt
  • shellcheck:负责脚本静态分析,可配合 VSCode 的 shellcheck 插件使用。
  • shfmt:Shell 脚本格式化工具,配合 shell-format 插件使用。

安装完成后,验证版本:

shellcheck --version
shfmt --version

3.2 VSCode 插件配置

在 VSCode 设置中(Ctrl + ,),可以针对 Shell 脚本进行一些定制化配置。推荐配置项如下(可在 settings.json 中直接修改):

{
    "workbench.settings.editor": "json",
    "code-runner.runInTerminal": true,
    "code-runner.preserveFocus": false,
    "code-runner.clearPreviousOutput": true,
    "code-runner.executorMap": {
         "shellscript": "bash $fileName"
    },
     "files.eol": "\n",
     "shellformat.path": "shfmt",
    "shellformat.arguments": ["-i", "4", "-bn", "-ci", "-sr"]

}

说明:

  • shellcheck.customArgs:设置检查级别,如 warningerror
  • shellcheck.exclude:忽略不需要的规则,例如当不可避免外部引用文件时可以排除 SC1090SC1091
  • shellcheck.runonType 实现实时检查,保存文件时也会触发。
  • [shellscript]:将 shell-format 设为默认格式化工具,并开启保存时自动格式化,同时强制换行符为 LF。
    code-runner 插件相关配置
"code-runner.runInTerminal": true,
    "code-runner.preserveFocus": false,
    "code-runner.clearPreviousOutput": true,
    "code-runner.executorMap": {
        "shellscript": "wsl bash"
    }
部分为code runner相关配置,
  • code-runner.runInTerminal: true:在集成终端运行(交互脚本、输入参数必备,避免输出面板无法交互)
  • code-runner.clearPreviousOutput: true:每次运行清空旧输出
  • code-runner.executorMap:指定 shellscript 类型文件的解释器
    快捷键:
    • Ctrl+Alt+N:运行代码
    • Ctrl+Alt+M:停止运行

点击右上角 ▶ Run Code 按钮 或 Ctrl+Alt+N
确认正常输出,无 \r: command not found 报错
如有换行报错:设置 files.eol 为 \n(LF),在settings.json 全局设置保存后,后续新建 .sh 脚本默认就是 LF 换行

在这里插入图片描述
看 VSCode 右下角状态栏:会显示 CRLF / LF,点击 CRLF → 选择 LF,保存文件即可
额外建议
Shell 脚本务必全程用 LF 换行符,不要混用 CRLF
WSL 开发时尽量把脚本放在 WSL 内部目录(~/xxx),减少 Windows 换行干扰

3.3 如何批量替换 shell 脚本中的 \n 为 LF,或者有啥工具能自动检测替换

方法 1:dos2unix(推荐,WSL / Git Bash / MSYS2)

  1. 安装
    WSL (Ubuntu/Debian)
    bash
    运行
sudo apt update
sudo apt install dos2unix

Git Bash / Windows:可通过 Chocolatey choco install dos2unix,或 MSYS2
bash
运行

pacman -S dos2unix
  1. 批量转换
    bash
    运行
# 当前目录所有 .sh 文件
dos2unix *.sh

# 递归整个文件夹所有 sh 脚本
find . -type f -name "*.sh" -exec dos2unix {} \;
3. 检测(查看是否还有 ^M)
bash
运行
# 查看单个文件
cat -v test.sh
# 批量查找含 \r 的脚本
find . -name "*.sh" -type f -exec grep -l $'\r' {} \;
方法 2:sed /awk 脚本批量替换(无需额外工具)
Linux/WSL
bash
运行
# 移除 \r 字符
sed -i 's/\r$//' *.sh
# 递归
find . -type f -name "*.sh" -exec sed -i 's/\r$//' {} \;

macOS sed 语法不同,不适用 Windows
方法 3:VSCode 批量处理
✅ 全局默认:设置 files.eol
json

{
    "files.eol": "\n"
}

✅ VSCode 批量替换已有文件
Ctrl+Shift+F 打开全局搜索
开启正则模式(.* 按钮)
查找框输入:\r
替换框留空
筛选文件:*.sh
全部替换,保存
插件方案:
搜索插件:Change End of Line / EditorConfig
EditorConfig 配置(新增 .editorconfig 文件)
ini

[*.sh]
end_of_line = lf
charset = utf-8

自动保持脚本为 LF 换行
方法 4:Git 全局配置(防止以后反复生成 CRLF)
bash
运行

# 关闭 Git 自动转换换行
git config --global core.autocrlf false
git config --global core.eol lf
windows 环境 ,使用 vscode 编辑器 安装的也有 wsl 怎么使用 dos2unix

一、先安装 WSL 内的 dos2unix

  1. 进入 VSCode WSL 终端
    VSCode 通过 Remote-WSL 插件连接 WSL(左下角绿色标识)
    打开集成终端 `Ctrl +``,此时终端就是 Ubuntu WSL bash
  2. 安装命令
    bash
    运行
sudo apt update
sudo apt install dos2unix

验证安装:
bash
运行

dos2unix --version
which dos2unix

二、两种目录场景使用 dos2unix
✅ 场景 1:脚本存放在 WSL 原生目录(推荐,如~/xxx)
bash
运行

# 进入脚本文件夹
cd ~/my-shell-scripts

# 单个脚本转换
dos2unix test.sh

# 当前目录所有 sh 脚本
dos2unix *.sh

# 递归整个文件夹所有 sh 脚本
find . -type f -name "*.sh" -exec dos2unix {} \;

# 验证是否还有 \r 回车符(^M)
cat -v test.sh
# 批量查找仍含 \r 的脚本
find . -name "*.sh" -type f -exec grep -l $'\r' {} \;

✅ 场景 2:脚本存放在 Windows 原生目录(C:/xxx/ D:/xxx,挂载在 /mnt/c//mnt/d/)
WSL 访问 Windows C 盘路径:/mnt/c/,D 盘:/mnt/d/
bash
运行

# 示例:进入 Windows C盘 Users 下的脚本目录
cd /mnt/c/Users/你的Windows用户名/Desktop/shell

# 转换
dos2unix *.sh
find . -type f -name "*.sh" -exec dos2unix {} \;

⚠️ 注意:Windows 编辑器可能会再次把行尾改回 CRLF,尽量把开发目录迁移到 WSL 内部目录(~/…),并设置 VSCode files.eol: “\n”
三、VSCode 基础全局防重复问题
设置默认行尾为 LF
json

{
    "files.eol": "\n"
}

Git 配置防止自动转 CRLF
bash
运行

git config --global core.autocrlf false
git config --global core.eol lf

可增加 .editorconfig 文件
ini

[*.sh]
end_of_line = lf
charset = utf-8

四、常见坑
直接修改 /mnt/c/ Windows 文件后,VSCode Windows 编辑器保存又变回 CRLF
最优方案:全程在 Remote-WSL 模式编辑 WSL 家目录内脚本,避免反复修改 Windows 盘符文件
权限报错
WSL 内部文件夹正常使用即可;/mnt/ 目录可适当调整权限或直接迁移项目
确认转换结果
cat -v xxx.sh 无 ^M 字符 = 纯 LF 换行,脚本不再报 \r: command not found
五、备选:纯 Windows 调用 dos2unix(非 WSL)
如需在原生 PowerShell / Git Bash 使用,可通过 Chocolatey 安装 dos2unix:
powershell
choco install dos2unix
六、最佳流程
VSCode Remote-WSL 连接 Ubuntu,把项目放到 ~/ 目录
WSL 安装 dos2unix,一次性批量转换历史脚本
VSCode 设置 files.eol: “\n”,以后新建脚本默认 LF,不再反复修复换行符

常见问题
问题一、Tips depend on target shell and yours is unknown. Add a shebang or a ‘shell’ directive.shellcheckSC2148

误原因
SC2148: Tips depend on target shell and yours is unknown. Add a shebang or a ‘shell’ directive.
ShellCheck 不知道你脚本用哪种 Shell(bash/sh/zsh/dash…),无法精准检查语法,因此报警告。
✅ 解决方法(3 种)
方法 1:脚本头部加正确 shebang(首选)
在 .sh 文件第一行添加解释器声明:
bash
运行

#!/bin/bash


# 后续脚本内容
echo "hello"

常用 shebang
bash:#!/bin/bash
sh (POSIX): #!/bin/sh
zsh:#!/bin/zsh
保存后警告立刻消失
方法 2:VSCode ShellCheck 配置指定 shell(全局)
打开 settings.json:
json

{
    "shellcheck.shell": "bash"
}

可选值:bash, sh, zsh, dash, ksh

问题二、[shfmt -i 4 -bn -ci -sr -d -] Exit code null: shfmt not installed
VSCode Shell 格式化插件调用了 shfmt 工具,但本机 / WSL 环境还没安装 shfmt,导致格式化失败、报错 shfmt not installed

环境安装 shfmt
方案 1:WSL Ubuntu(优先,Remote-WSL 开发)
打开 VSCode WSL 终端,执行:
bash
运行
# 方法A:apt (新版Ubuntu可用)
sudo apt update
sudo apt install shfmt

# 方法B:go 安装(通用方式)
sudo apt install golang
go install mvdan.cc/sh/v3/cmd/shfmt@latest

# 把go bin加入环境变量(~/.bashrc)
echo 'export PATH=$PATH:~/go/bin' >> ~/.bashrc
source ~/.bashrc

# 验证
shfmt --version

问题三:运行提示 /bin/bash : 无法将 “/bin/bash” 项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,

你现在用的是 Windows 原生 PowerShell / CMD 终端,不是 WSL / Git Bash 终端。
Windows 原生环境本身没有 /bin/bash 这个路径(这是 Linux/WSL 的路径格式),所以直接输入 /bin/bash 会报错。
方法 1:确认当前终端模式 + 正确调用 bash
情况 A:你要在 WSL 里运行(推荐)
VSCode 确认左下角是 WSL: Ubuntu(Remote-WSL 模式)
如果不是:左下角点击绿色远程按钮 → 重新连接 WSL Ubuntu
打开 WSL 集成终端 `Ctrl+``,此时是 Ubuntu bash,可正常用:
bash
运行
/bin/bash
不要在 Windows PowerShell 面板里直接执行 /bin/bash

方案 A:Remote-WSL 模式(推荐,全程在 WSL Ubuntu 里开发)
确认 VSCode 左下角显示 WSL:Ubuntu(Remote-WSL 连接成功)
settings.json 配置:
json

{
    "code-runner.runInTerminal": true,
    "code-runner.clearPreviousOutput": true,
    "code-runner.preserveFocus": false,
    "code-runner.executorMap": {
        "shellscript": "bash $fileName"
    },
    "files.eol": "\n"
}

在这里插入图片描述

原理:WSL 环境原生支持 bash,不再写硬编码 /bin/bash
运行:Ctrl+Alt+N,在 WSL bash 终端执行脚本

3.5 自动化持续检测

ShellCheck + VSCode + EditorConfig:实时校验格式
pre-commit Git 钩子(pre-commit + pre-commit-hooks)
使用 end-of-file-fixer 自动统一行尾为 LF,提交代码前自动修复
定期脚本检查:
bash
运行

find . -name "*.sh" -exec grep -l $'\r' {} \;

✅ 最佳实践
日常开发:用 WSL + Remote-WSL + EditorConfig + files.eol: “\n”,从源头避免 CRLF
存量修复:优先用 dos2unix 递归批量转换,一步到位
验证:运行 cat -v xxx.sh,确认无 ^M 标记

4. 强化调试能力

传统 Shell 调试仅靠 set -x / set +x 控制局部日志,而借助 VSCode 的调试器插件,我们可以实现断点调试、变量查看等高级体验。

4.1 安装 Bash Debug 扩展

在 VSCode 扩展商店中搜索 Bash Debug(发布者 geraldo)并安装。该插件基于 bashdb,提供了图形化调试前端。

在 WSL2 中安装调试后端 bashdb

sudo apt install -y bashdb

验证安装:

bashdb --version

4.2 创建调试配置文件

在项目根目录下新建 .vscode/launch.json(如果已有则追加配置),内容如下:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "bashdb",
      "request": "launch",
      "name": "Debug Bash Script",
      "program": "${file}",
      "cwd": "${fileDirname}",
      "args": []
    }
  ]
}

配置含义:

  • type:指定调试器类型为 bashdb(即 Bash Debug 扩展注册的类型)。
  • program${file} 代表当前在编辑器中打开的文件,方便直接调试。
  • cwd:工作目录设为脚本所在目录。
  • args:可传入脚本所需的命令行参数。

如果调试需要传入参数,可以在 VSCode 的“运行与调试”面板中通过下拉选择配置,修改 args 数组即可。

4.3 断点调试实战

编写一个测试脚本 test_debug.sh

#!/bin/bash

NAME="VSCode"
COUNT=0

for i in {1..5}; do
    COUNT=$((COUNT + i))
done

echo "Hello, ${NAME}!"
echo "Sum: ${COUNT}"

在 VSCode 行号左侧单击打上断点(例如 COUNT=$((COUNT + i)) 这一行)。按 F5 启动调试,程序将在断点处暂停,此时可以在调试面板中查看变量 COUNTi 的值,支持单步执行、跳过、进入等常用调试操作。

VSCode Remote-WSL 完整 Shell 断点调试教程

前置条件

  • VSCode 左下角是 WSL: Ubuntu(远程 WSL 模式)
  • 已安装插件(WSL 远程扩展里安装)
  • Bash Debug(rogalmic):断点调试核心插件
  • ShellCheck:语法检测
  • 脚本首行必须有 shebang,换行 LF
  • 脚本放在 WSL 内部目录(/home/avic/xxx),最好不要放在 /mnt/e/ 等 Windows 挂载盘
一、创建调试配置 launch.json

左侧边栏点击「运行和调试」(虫子图标)
点击 创建 launch.json 文件 → 选择 Bash Debug
自动生成配置,使用下面标准 WSL 配置覆盖:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "bashdb",
            "request": "launch",
            "name": "调试当前Shell脚本",
            "program": "${file}",
            "args": [],
            "cwd": "${workspaceFolder}",
            "terminalKind": "integrated",
            "showDebugTerminal": true
        }
    ]
}

args 数组可以传脚本入参,例:“args”:[“test1”,“123”]
在这里插入图片描述
在调试脚本下新建.vscode文件夹,文件夹下新建 launch.json 脚本

二、打断点
打开 .sh 脚本,点击行号左侧空白处,出现红色圆点即断点生效。
只对可执行代码行生效,空行、注释无法打断点。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件打断点进行调试

在这里插入图片描述
三、调试快捷键(核心)
表格
快捷键 功能

  • F5 启动调试,运行到下一个断点
  • F10 单步跳过:执行当前行,跳到下一行,不进入函数
  • F11 单步步入:进入自定义函数内部调试
  • Shift + F11 单步跳出:退出当前函数 / 脚本
  • Shift + F5 停止调试
  • Ctrl + Shift + F5 重新启动调试
    四、调试面板功能
    变量:实时查看所有定义变量 $a $b $c
    监视:手动输入表达式实时求值,如 $((a*b))
    调用堆栈:查看函数调用层级
    调试控制台:调试过程中手动输入命令修改变量、执行语句
    五、传入脚本参数调试
    修改 launch.json 的 args 字段,例如脚本需要传入 start 8080:
    json
"args": ["start", "8080"]

脚本内通过 $1 $2 获取参数。
六、常见报错解决

  1. 找不到文件 / 路径 e:/xxx
    根源:脚本放在 Windows 挂载盘 /mnt/e/
    解决:复制脚本到 WSL 家目录 /home/avic/ 再调试
    bash
    运行
cp /mnt/e/tiaoshi/shell1.sh ~/
  1. SC2148 警告
    脚本第一行添加 #!/bin/bash
  2. 换行 \r: command not found
    WSL 终端执行:
    bash
    运行
dos2unix 脚本名.sh

VSCode 设置默认行尾 files.eol: “\n”

5. 统一编辑器行为与快捷键

为了提升脚本编写效率,可以自定义一些 VSCode 快捷键(Ctrl+K Ctrl+S 打开键盘快捷方式)。推荐绑定:

  • 运行当前脚本:绑定 Ctrl+R 执行终端中的 bash ${file}
  • 折叠/展开代码块:利用 VSCode 自带的折叠快捷键 Ctrl+Shift+[Ctrl+Shift+]

以下是通过 tasks.json 快速运行脚本的方式,在 .vscode/tasks.json 中添加:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Run Current Script",
      "type": "shell",
      "command": "bash",
      "args": ["${file}"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": []
    }
  ]
}

之后使用 Ctrl+Shift+B 即可快速执行当前脚本,输出结果显示在终端中。

6. 进阶技巧与最佳实践

6.1 代码片段(Snippets)

利用 VSCode 用户自定义代码片段,可以为 Shell 脚本设置常用模板。通过 F1Preferences: Configure User Snippetsshellscript 打开编辑。例如添加 #!/bin/bash 头部模板:

{
  "shebang": {
    "prefix": "!",
    "body": ["#!/bin/bash", "", "set -euo pipefail", "", "$0"],
    "description": "Insert shebang with strict mode"
  }
}

输入 ! 按下 Tab 即可展开。

6.2 集成 ShellCheck 到 CI/CD

为保证团队脚本质量,可以在 CI/CD 流水线中集成 ShellCheck 检查。例如在 GitHub Actions 中添加:

- name: ShellCheck
  run: shellcheck scripts/*.sh

与本地 VSCode 环境保持一致,避免代码合并后才发现问题。

6.3 多 Shell 支持

如果项目同时使用 Bash 与 Zsh 脚本,Bash IDEBash Debug 一样能正常工作。在 VSCode 文件底部状态栏可以手动选择关联的语言模式(Shell ScriptBashZsh)以确保正确的语法高亮和检查。

7. 总结

本文从插件安装、环境配置、调试器搭建到高级技巧,完整介绍了基于 VSCode 的 Shell 脚本开发调试环境的准备过程。合理利用 VSCode 扩展生态,足以将轻量级的命令行脚本开发体验提升到接近专业 IDE 的水平。

经过上述配置,你可以获得:

  • 实时语法检查与静态分析
  • 自动格式化与代码片段
  • 图形化断点调试
  • 一键运行与 CI 集成支持

希望这套环境能帮助你更高效地编写和维护 Shell 脚本。

更多推荐