在 Windows 批处理和 Linux Bash 中运行的单个脚本? [英] Single script to run in both Windows batch and Linux Bash?

查看:21
本文介绍了在 Windows 批处理和 Linux Bash 中运行的单个脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以编写在 Windows(视为 .bat)和 Linux(通过 Bash)中执行的单个脚本文件?

Is it possible to write a single script file which executes in both Windows (treated as .bat) and Linux (via Bash)?

我知道两者的基本语法,但没有弄清楚.它可能会利用一些 Bash 晦涩的语法或一些 Windows 批处理器故障.

I know the basic syntax of both, but didn't figure out. It could probably exploit some Bash's obscure syntax or some Windows batch processor glitch.

要执行的命令可能只是一行来执行其他脚本.

The command to execute may be just a single line to execute other script.

目的是为 Windows 和 Linux 提供一个应用程序启动命令.

The motivation is to have just a single application boot command for both Windows and Linux.

更新: 系统原生"shell 脚本的需要是它需要选择正确的解释器版本,符合某些众所周知的环境变量等.安装额外的环境如 CygWin 不是可取的- 我想保留下载并运行"的概念.

Update: The need for system's "native" shell script is that it needs to pick the right interpreter version, conform to certain well-known environment variables etc. Installing additional environments like CygWin is not preferable - I'd like to keep the concept "download & run".

Windows 唯一需要考虑的其他语言是 Windows Scripting Host - WSH,它从 98 开始就默认设置了.

The only other language to consider for Windows is Windows Scripting Host - WSH, which is preset by default since 98.

推荐答案

我做的是使用cmd的标签语法作为注释标记.标签字符,一个冒号 (:),在大多数 POSIXish shell 中等同于 true.如果您在标签字符后面紧跟一个不能在 GOTO 中使用的字符,那么注释您的 cmd 脚本应该不会影响您的 cmd 代码.

What I have done is use cmd’s label syntax as comment marker. The label character, a colon (:), is equivalent to true in most POSIXish shells. If you immediately follow the label character by another character which can’t be used in a GOTO, then commenting your cmd script should not affect your cmd code.

技巧是在字符序列:;"之后放置代码行.如果您主要编写单行脚本,或者可以为多行 cmd 编写一行 sh,以下可能没问题.不要忘记 $? 的任何使用都必须在下一个冒号 : 之前,因为 : 会重置 $?到 0.

The hack is to put lines of code after the character sequence ":;". If you’re writing mostly one-liner scripts or, as may be the case, can write one line of sh for many lines of cmd, the following might be fine. Don’t forget that any use of $? must be before your next colon : because : resets $? to 0.

:; echo "Hi, I’m ${SHELL}."; exit $?
@ECHO OFF
ECHO I'm %COMSPEC%

一个非常人为的保护 $? 的例子:

A very contrived example of guarding $?:

:; false; ret=$?
:; [ ${ret} = 0 ] || { echo "Program failed with code ${ret}." >&2; exit 1; }
:; exit
ECHO CMD code.

跳过 cmd 代码的另一个想法是使用 heredocs 以便 shcmd 代码视为未使用的字符串,然后 cmd 解释它.在这种情况下,我们确保我们的 heredoc 的分隔符都被引用(以阻止 sh 在使用 sh 运行时对其内容进行任何类型的解释)并以 : 以便 cmd 像任何其他以 : 开头的行一样跳过它.

Another idea for skipping over cmd code is to use heredocs so that sh treats the cmd code as an unused string and cmd interprets it. In this case, we make sure that our heredoc’s delimiter is both quoted (to stop sh from doing any sort of interpretation on its contents when running with sh) and starts with : so that cmd skips over it like any other line starting with :.

:; echo "I am ${SHELL}"
:<<"::CMDLITERAL"
ECHO I am %COMSPEC%
::CMDLITERAL
:; echo "And ${SHELL} is back!"
:; exit
ECHO And back to %COMSPEC%

根据您的需要或编码风格,交错 cmdsh 代码可能有意义也可能没有意义.使用 heredocs 是执行这种交错的一种方法.但是,这可以通过 GOTO 技术进行扩展:

Depending on your needs or coding style, interlacing cmd and sh code may or may not make sense. Using heredocs is one method to perform such interlacing. This could, however, be extended with the GOTO technique:

:<<"::CMDLITERAL"
@ECHO OFF
GOTO :CMDSCRIPT
::CMDLITERAL

echo "I can write free-form ${SHELL} now!"
if :; then
  echo "This makes conditional constructs so much easier because"
  echo "they can now span multiple lines."
fi
exit $?

:CMDSCRIPT
ECHO Welcome to %COMSPEC%

通用注释当然可以用字符序列:#:;#来完成.空格或分号是必要的,因为如果 sh 不是标识符的第一个字符,则 # 将其视为命令名称的一部分.例如,在使用 GOTO 方法拆分代码之前,您可能希望在文件的第一行中编写通用注释.然后你可以告诉你的读者为什么你的脚本写得如此奇怪:

Universal comments, of course, can be done with the character sequence : # or :;#. The space or semicolon are necessary because sh considers # to be part of a command name if it is not the first character of an identifier. For example, you might want to write universal comments in the first lines of your file before using the GOTO method to split your code. Then you can inform your reader of why your script is written so oddly:

: # This is a special script which intermixes both sh
: # and cmd code. It is written this way because it is
: # used in system() shell-outs directly in otherwise
: # portable code. See https://stackoverflow.com/questions/17510688
: # for details.
:; echo "This is ${SHELL}"; exit
@ECHO OFF
ECHO This is %COMSPEC%

因此,据我所知,一些想法和方法可以实现 shcmd 兼容的脚本而没有严重的副作用(并且没有 cmdcode> 输出 '#' 不是内部或外部命令,也不是可运行的程序或批处理文件.).

Thus, some ideas and ways to accomplish sh and cmd-compatible scripts without serious side effects as far as I know (and without having cmd output '#' is not recognized as an internal or external command, operable program or batch file.).

这篇关于在 Windows 批处理和 Linux Bash 中运行的单个脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆