我编写了一个批处理脚本来增强命令提示符上的工作流程

2025-06-07

我编写了一个批处理脚本来增强命令提示符上的工作流程

是的,亲爱的读者们,我只是写了一个批处理脚本,而不是 bash 脚本!

Batch 是编写 Windows 命令提示符(cmd.exe)脚本的语言。

这个脚本有什么特别之处?

这就是我要讨论的内容。

我为什么需要这个脚本(也就是问题所在)

虽然 WSL 对于想要利用 Linux 命令和环境的 Windows 用户来说是一个强大的工具,但每次只想运行一个命令时打开 WSL 终端通常很麻烦,而实际上您正在使用 powershell 或命令提示符。

我知道你现在会说什么。你会说:“兄弟,用 wsl cli 就行了!”
但实际上,不仅仅是 cli 能帮你搞定一切!

假设您习惯于使用 Linux 环境中的一些命令,这些命令不是任何 Linux 二进制文件,而是在初始化 Shell 时获取的一些函数和别名。

例如这个bash函数(非常方便)

extract ()
{
    local file="$1";
    if [ -z "$file" ]; then
        printf "\033[1;31mNo file specified\n\033[0m" 1>&2;
        return 1;
    fi;
    if [ ! -f "$file" ]; then
        printf "\033[1;31mFile '%s' not found\n\033[0m" "$file" 1>&2;
        return 1;
    fi;
    local ext="${file#*.}";
    local extractor;
    local options="";
    case "$ext" in
        tar.bz2 | tbz2 | tar)
            extractor="tar";
            options="xvf"
        ;;
        tar.gz | tgz)
            extractor="tar";
            options="xzvf"
        ;;
        tar.xz)
            extractor="tar";
            options="Jxvf"
        ;;
        bz2)
            extractor="bunzip2"
        ;;
        rar)
            extractor="unar";
            options="-d"
        ;;
        gz)
            extractor="gunzip"
        ;;
        zip)
            extractor="unzip"
        ;;
        xz)
            extractor="unxz"
        ;;
        7z)
            extractor="7z";
            options="x"
        ;;
        Z)
            extractor="uncompress"
        ;;
        *)
            printf "\033[1;31mUnsupported file type: %s\n\033[0m" "$file" 1>&2;
            return 1
        ;;
    esac;
    if ! "$extractor" $options "$file"; then
        printf "\033[1;31mError extracting '%s'\n\033[0m" "$file" 1>&2;
        return 1;
    fi
}
Enter fullscreen mode Exit fullscreen mode

我可以使用此函数提取任何类型的(几乎)存档文件extract,并结合所有必要的工具。只需一个函数即可提取所有文件。此函数和另一个函数位于我的WSL目录.bash_functions中的文件中$HOME

或者这些别名 -

alias gla='git log --oneline --graph --all'
alias la='exa -a --icons --group-directories-first' # exa needs to be preinstalled
alias ll='exa -alhF --icons' # exa needs to be preinstalled
alias cdf='cd $(fd -t d | fzf)' # fd-find and fzf needs to be preinstalled 
alias fvim='nvim $(fzf --preview="bat --color=always {}" --bind shift-up:preview-page-up,shift-down:preview-page-down)' # nvim, bat and fzf needs to be preinstalled
alias ff='fzf --preview=less --bind shift-up:preview-page-up,shift-down:preview-page-down)' # fzf and less needs to be preinstalled
Enter fullscreen mode Exit fullscreen mode

这些是我的最显着的别名(我想是的),它们存在于.bash_aliases我的WSL$HOME目录中

wsl cli 非常适合运行安装在 WSL 系统中的 Linux 二进制文件,例如在 Linux 环境(WSL)之外的命令提示符中。

但是所提供的选项都不能让您在其外部运行自定义命令。

解决方案

第一种方法

我想,“让我们尝试在 Windows 中复制命令...”
但很快我意识到这非常不方便,因为虽然 powershell 具有更好的语法和配置选项,尽管它具有与 bash 几乎以相同方式编写的功能,但复制自定义命令(那些功能和别名)将非常困难并且需要在 Windows 中安装所需的软件。

至于 cmd,想都别想。
另外,powershell 和 cmd 不支持像 bash/zsh 这样的别名。最后,我找不到任何类似.bashrc命令提示符的初始化脚本(可能根本就不存在,如果有的话请告诉我)。

现在你可能会再次说:“嘿,如果你想要别名,为什么不在 cmd 中使用 doskey 呢?”
再说一次DOSKEY是 Windows 开发人员的另一个非常不方便的发明。它是一个可以为交互式命令行创建宏的命令。它不方便是因为——

  • DOSKEY宏不能在管道的任何一侧使用:和都会失败someMacro|findstr '^'dir|someMacro
  • 它们不能在 FOR /F 命令中使用:for /f %A in ('someMacro') do ...失败。
  • 使用DOSKEY编写的宏必须用 % 括起来(例如,如果宏的名称是 ,grep那么我需要将其作为 %grep% 运行)。有关更多信息,请参阅此 StackExchange 答案。

是的,我在研究之后就停在那里了。

第二种方法

精彩的部分来了。我意识到复制命令会浪费时间。所以,让我尝试一下在命令提示符下以完全相同的方式访问我拥有的 wsl 的每一个命令。如果没有 init 脚本,我必须创建一个可以执行 bash 函数和别名以及所有二进制文件的命令。

所以,我决定编写一个批处理脚本。

为什么不使用 powershell 脚本?

因为 powershell 比 cmd 慢。虽然用 powershell 写脚本更容易,但只要我知道只需要写一个脚本,而且可能只需要一个函数,我觉得用 cmd 写脚本还是值得一试的。而且,一路上我还能学到新东西!
呦吼!

步骤

  1. 在我的用户主目录中创建了一个目录“bin”。在环境变量中添加了 bin 的路径。
  2. 在 bin 中创建一个文件runbash.bat。这将是脚本。
  3. 批处理的语法对我来说太难懂了。等等。我们一步一步来看脚本代码。我会尽力解释清楚。
  4. 第一行 - @echo off。它将防止脚本运行时命令输出扰乱控制台。
  5. 第二行 - setlocal enabledelayedexpansion。这用于在循环内动态处理变量。它启用延迟扩展,从而允许在同一命令行中使用变量(使用 !VAR! 而不是 %VAR%)。
  6. set CMDLINE=初始化一个名为的空变量CMDLINE,该变量将用于累积命令行参数。
  7. :loop标志着循环的开始。
  8. if "%~1"=="" goto end检查第一个参数(%~1)是否为空。如果是,脚本将跳转到:end标签并停止处理参数。
  9. set CMDLINE=!CMDLINE! %~1将当前参数(%~1)附加到CMDLINE变量,构建命令行。
  10. shift将命令行参数左移,因此%2变为%1%3变为%2,依此类推。这实际上删除了第一个参数,并允许循环处理下一个参数。
  11. goto loop重复循环来处理下一个参数。
  12. :end:标记循环的结束,此时所有参数均已处理完毕。
  13. bash -ic "!CMDLINE!"CMDLINE在默认 Bash shell(即默认 wsl 的 bash)中执行累积的命令 ( )。使用-i(interactive) 选项确保它在交互式 shell 中运行。该-c选项告诉 Bash 执行命令字符串。

最终的剧本是这样的。

剧本

@echo off
setlocal enabledelayedexpansion
set CMDLINE=
:loop
if "%~1"=="" goto end
set CMDLINE=!CMDLINE! %~1
shift
goto loop
:end
bash -ic "!CMDLINE!"
Enter fullscreen mode Exit fullscreen mode

就这样!现在我的 Windows 环境中有了一个新命令,它让我可以直接在 cmd 中运行 WSL 环境中的任何自定义命令!太酷了!
看看,效果太棒了!

在 wsl 之外成功运行 bash 别名

最后的想法

所以第二种方法其实是个不错的决定。我节省了很多时间和精力。

现在这个命令大大提高了我的工作效率。

另外,我的默认 wsl 发行版是 Void Linux,而不是 Ubuntu。因此,bash shell 初始化不需要太多时间,所有命令都能快速运行runbash

另外,还有一个好处就是我不需要打开单独的git-bash实例,也不wsl需要运行一些 bash 文件。我可以在 Windows 上编写 bash,然后从命令提示符执行它们,而无需打开 WSL。

运行 NetworkChuck 的 bash 教程中的 eldenring 基本 bash 脚本

如果您发现这篇文章很有帮助,如果这个博客为您的时间和精力增添了一些价值,请点赞并与您的朋友分享以表达您的喜爱。

欢迎通过TwitterLinkedInGitHub与我联系:)

祝你编程愉快🧑🏽‍💻👩🏽‍​​💻!祝你拥有美好的一天!🚀

文章来源:https://dev.to/studio1hq/i-wrote-a-batch-script-to-enhance-my-workflow-on-command-prompt-2476
PREV
您如何了解最新的技术发展?
NEXT
AWS API 架构