每当我使用批处理脚本作为 Windows 应用程序打开代码文件时,我都会尝试使用批处理脚本在 Ubuntu 终端内的 Neovim 中运行代码文件。 我可以成功运行
set "command=nvim \"%file_path%\""
,它将 nvim 附加到文件路径,以便在 Ubuntu 终端内作为命令运行。这成功地打开了 neovim 内 Ubuntu 终端内的代码文件。
但我遇到了一个问题,如果我使用 set "command=cd \"%dir_path%\" && nvim \"%file_path%\""
,它添加了 cd 命令,然后添加了 nvim 命令,则无法打开代码文件。
当cd命令单独运行而不是与nvim命令一起运行时,Ubuntu终端运行后立即退出。 当 cd 命令与 nvim 命令一起运行时,Ubuntu 终端不用于运行 nvim,而是在 cmd.exe 终端内运行,然后显示以下错误。
E303: Unable to open swap file for ""\mnt\c\Users\marci\OneDrive\OB", recovery impossible Press ENTER or type command to continue
这是我的全部代码。您可以看到一些用
rem
注释掉的行代码。这是我无法运行的其他代码/它们用于调试目的。
@echo off
rem Get file address
set "file_address=%~1"
rem Replace backslashes (\) with forward slashes (/) in file path
set "file_path=%file_address:\=/%"
rem Extract directory path from file path
for %%I in ("%file_path%") do set "dir_path=%%~dpI"
rem Replace backslashes (\) with forward slashes (/) in directory path
set "dir_path=%dir_path:\=/%"
rem Remove trailing backslash from directory path
if "%dir_path:~-1%"=="\" set "dir_path=%dir_path:~0,-1%"
rem Remove first 2 characters (assuming it's the drive letter and backslash)
set "file_path=%file_path:~2%"
set "dir_path=%dir_path:~2%"
rem Prepend /mnt/c/ to the paths to properly reference the C: drive in WSL
set "file_path=/mnt/c%file_path%"
set "dir_path=/mnt/c%dir_path%"
rem Set command to change directory and open file in nvim
rem set "command=cd \"%dir_path%\" && nvim \"%file_path%"\"
rem set "command=cd \"%dir_path%\""
set "command=nvim \"%file_path%\""
rem Copy file & directory path into clipboard
rem echo "%file_path%" | clip
rem echo "%dir_path%" | clip
rem echo "%command%" | clip
rem Launch ubuntu.exe with cmd.exe command
start ubuntu.exe run %command%
我已尽我所知来解决这个问题,不幸的是我不知道从这里到哪里去。我相信我的知识有缺陷或缺乏如何使用批处理脚本使用 cd 命令。但我找不到任何可以解决这个问题的帮助。 根据我的理解, cd 在批处理脚本中的处理方式不同,这就是为什么它没有被正确传递到 Ubuntu 终端的原因。但我也不知道这是否正确。
你能看出我哪里错了吗?为什么会导致这个错误? 我为我的无知感到非常抱歉。
这里有一些问题:
路径转换可以改进 -
\
到/
可以等到我们完成文件和目录的提取:
for /f delims^= %%I in (^""%~dp1."^") do (
set "file_path=%%~pI\%~nx1"
set "dir_path=%%~pI"
)
set "file_path=/mnt/c%file_path:\=/%"
set "dir_path=/mnt/c%dir_path:\=/%"
command
包含元字符(即 &
),因此应加引号:
start ubuntu.exe run "%command%"
当使用引号与
start
时,第一个参数(窗口标题)应该存在(可以为空):
start "" ubuntu.exe run "%command%"
您正在使用
\
来转义引号,这在 cmd.exe
中不起作用 - 在这里,其符号是 ^
,如下所示:
set "command=cd ^"%dir_path^" && nvim ^"%file_path%^""
然而,这是不必要的 - 因为
command
本身将被引用,除了 %
(以及 !
应该启用延迟扩展)之外的每个字符都将失去其语义,允许您编写:
set "command=cd "%dir_path%" && nvim "%file_path%""
这还不够好;当
cmd.exe
扩展我们的变量时,命令将如下所示:
start ubuntu.exe run "nvim "%file_path%""
如果
file_path
包含空格,这可能(并且将会)很容易中断。这就引出了最后一点:
这里不需要使用
"
- 那时我们将使用 Ubuntu,因此可以使用 '
来引用:
set "command=cd '%dir_path%' && nvim '%file_path%'"
start "" ubuntu.exe run "%command%"
完整脚本:
for /f delims^= %%I in (^""%~dp1."^") do (
set "file_path=%%~pI\%~nx1"
set "dir_path=%%~pI"
)
set "file_path=/mnt/c%file_path:\=/%"
set "dir_path=/mnt/c%dir_path:\=/%"
set "command=cd '%dir_path%' && nvim '%file_path%'"
start "" ubuntu.exe run "%command%"
这就引出了一个问题:你为什么要这样做......