【问题标题】:Use shebang/hashbang in Windows Command Prompt在 Windows 命令提示符中使用 shebang/hashbang
【发布时间】:2011-07-25 14:55:18
【问题描述】:

我目前正在使用 serve 脚本在 Windows 7 上使用 Node.js 提供目录。它在 MSYS shell 或使用 sh 时运行良好,因为我已经放置了 node.exe 和服务脚本在我的 ~/bin (在我的 PATH 中)中,只输入“serve”就可以了,因为它是 Shebang (#!) 指令,它告诉 shell 使用 node.js 运行它。

但是,Windows 命令提示符似乎不支持没有 *.bat 或 *.exe 扩展名的普通文件,也不支持 shebang 指令。是否有任何注册表项或其他黑客可以强制这种行为脱离内置的cmd.exe

我知道我可以编写一个简单的批处理文件来使用 node 运行它,但我想知道它是否可以在内置的方式中完成,所以我不必为每个脚本编写脚本这样?

更新:实际上,我在想,是否可以为所有“找不到文件”等编写一个默认处理程序,我可以在sh -c 内自动尝试执行?

谢谢。

【问题讨论】:

  • 您是否考虑过回来更新已接受的答案?你接受的那个是不正确的,你在它下面有一个很好的选择。

标签: windows unix shell command-prompt shebang


【解决方案1】:

是的,这可以使用PATHEXT 环境变量来实现。例如也用于注册.vbs.wsh 脚本以“直接”运行。

首先,您需要扩展 PATHEXT 变量以包含该服务脚本的扩展名(在下面我假设扩展名是 .foo,因为我不知道 Node.js)

默认值是这样的:

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

您需要(通过控制面板)将其更改为如下所示:

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.FOO

使用控制面板(控制面板 -> 系统 -> 高级系统设置 -> 环境变量是保持 PATHEXT 变量值所必需的。

然后您需要使用命令FTYPEASSOC 为该扩展注册正确的“解释器”:

ASSOC .foo=FooScript
FTYPE FooScript=foorunner.exe %1 %*

(以上示例无耻地摘自ftype /?提供的帮助。)

ASSOC 和 FTYPE 将直接写入注册表,因此您需要一个管理帐户来运行它们。

【讨论】:

  • 这和shebang不一样。 shebang 适用于 any 文件;这仅适用于特定的文件扩展名。完全不同的概念。
  • 但它会让用户毫不费力地运行文件。
  • @Mehrdad 这基本上是 shebang 的“Windows 等价物”。
  • 我从这篇文章中学到了很多。它让我想起了我编写的将 .jar 文件与 java.exe 相关联的批处理脚本:gist.github.com/djangofan/4144970
  • 虽然这很完美,但它会驱动文件中的 shebang 行变得荒谬 - 也许,在 Windows 下,最好完全忘记使用 shebang 并完全使用自定义文件(如上所述)而是扩展名?! (至少这是我的教训)
【解决方案2】:

命令提示符不支持 shebang ,但是有很多针对不同语言的混合技术,您可以将批处理和其他语言语法组合在一个文件中。由于您的问题涉及 node.js,这里是批处理-node.js 混合(使用.bat.cmd 扩展名保存):

0</* :{
        @echo off
        node %~f0 %*
        exit /b %errorlevel%
:} */0;


console.log(" ---Self called node.js script--- ");

console.log('Press any key to exit');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', process.exit.bind(process, 0));

可以使用许多其他语言来完成,例如 Ruby、Perl、Python、PHP 等。

【讨论】:

  • 哇!这真的很好用。最好的解决方案 IMO,因为它不需要更改系统并且适用于所有口译员。
  • 这是一个聪明的技巧。您是否有关于如何为其他语言完成此操作的参考/链接?特别是,我一直在尝试获得 Python 的等价物,但在它重新启动 python 解释器中的脚本之前,我无法避免 cmd 打印一行(到目前为止我最接近:rem="""\n@python.exe %~f0 %* &amp; @exit /b %errorlevel%\n"""; del rem\n Cmd 打印第一行: rem=""")
  • @sdenham - 检查这个 -> stackoverflow.com/a/41642050/388389
  • 谢谢!你让我免于被这个问题困扰的时间比我能承受的要长得多。
【解决方案3】:

不,没有办法“强制”命令提示符执行此操作。

Windows 只是 不是像 Unix/Linux 那样设计的

有没有类似的shell扩展

我没听说过,但应该在超级用户上问这个问题,而不是在这里。

【讨论】:

  • 可能的。看我的回答
【解决方案4】:

这是一种强制 Windows 支持 shebang 的简单方法,但它对文件命名有一个警告。将以下文本复制到批处理文件中,并遵循 REM cmets 中的总体思路。

@echo off

REM This batch file adds a cheesy shebang support for windows
REM Caveat is that you must use a specific extension for your script files and associate that extension in Windows with this batch program.
REM Suggested extension is .wss (Windows Shebang Script)
REM One method to still easily determine script type visually is to use double extensions.  e.g.  script.pl.wss

setlocal enableextensions disabledelayedexpansion
if [%1] == [] goto usage

for /f "usebackq delims=" %%a IN (%1) do (
  set shebang=%%a
  goto decode_shebang
)

:decode_shebang
set parser=%shebang:~2%
if NOT "#!%parser%" == "%shebang%" goto not_shebang

:execute_script
"%parser%" %*
set exit_stat=%errorlevel%
echo script return status: %exit_stat%
goto finale

:not_shebang
echo ERROR script first line %shebang% is not a valid shebang
echo       maybe %1 is not a shebanged script
goto finale

:usage
echo usage: %0 'script with #! shebang' [scripts args]+
echo        This batch file will inspect the shebang and extract the
echo        script parser/interpreter which it will call to run the script

:finale
pause
exit /B %exit_stat%

【讨论】:

    【解决方案5】:

    没有办法执行随机文件,除非它是一个实际的可执行二进制文件。 Windows CreateProcess() 函数不是为它设计的。它唯一可以执行的文件是那些带有MZ 魔法或带有%PATHEXT% 列表扩展名的文件。

    但是,CMD 本身通过EXTPROC 子句对自定义解释器的支持有限。限制是解释器在执行时也应该支持和省略这个子句。

    【讨论】:

      猜你喜欢
      • 2014-01-09
      • 2014-02-08
      • 2022-06-20
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      相关资源
      最近更新 更多