在 Windows cmd.exe 的同一命令行中设置和使用变量

Ale*_*nov 115 windows shell command-line

在 Bash 中,我可以EDITOR=vim command并且command将使用EDITORset to运行vim,但这不会影响EDITORshell 本身中的值。是否有可能做到这一点cmd.exe

Von*_*onC 77

请注意,这cmd /C "set "EDITOR=vim" && echo %EDITOR%"是行不通的。
也不会cmd /C "setlocal ENABLEDELAYEDEXPANSION && set "EDITOR=vim" && echo !EDITOR!"

你需要:

  • /V选项,则使用使延迟的环境变量扩展!为定界符。
  • 命令和&&(或添加引号)之间没有空格

那是:

C:\> cmd /V /C "set EDITOR=vim&& echo '!EDITOR!'"
'vim'
# or
C:\> cmd /V /C "set "EDITOR=vim" && echo '!EDITOR!'"
'vim'
Run Code Online (Sandbox Code Playgroud)

正如下面提到maoizm,它是cmd /V /C没有 cmd /C /V(这将工作)


我想不出有什么实际原因你会在单个命令的上下文中真正想要这个

通常,当您必须替换在长命令行中多次使用的值时,您需要这样做。
例如,要将文件部署到 Nexus(多行以提高可读性):

cmd /v /c "set g=com.agroup&& set a=anArtifact&& set v=1.1.0&& \
           mvn deploy:deploy-file -Dfile=C:\path\!a!-!v!.jar \
           -Dpackaging=jar -DgroupId=!g! -DartifactId=!a! -Dversion=!v! \
           -DrepositoryId=nexus 
           -Durl=http://myserver/nexus/content/repositories/my-repo/"
Run Code Online (Sandbox Code Playgroud)

不必在长而复杂的命令行中替换组、工件(使用 2 次)和版本,您可以在所述命令的开头编辑它们。操作和更改参数值更清晰/更容易。

  • @DerekGreer 这对于读取环境变量的应用程序也很有用(并且通常在 *Nix 中使用)。(例如`EDITOR=emacs git commit`)在windows上,它还可以用于从自定义位置加载DLL,通过设置DEVPATH https://docs.microsoft.com/en-us/dotnet/framework/configure-apps /how-to-locate-assemblies-by-using-devpath?redirectedfrom=MSDN (3认同)
  • 在我的 Windows 10 版本 1607 的机器上进行测试,cmd 提示符崩溃。 (2认同)
  • 注意:有趣的是:在这种情况下,开关的顺序很重要。`cmd /v/c "..."` 有效,但 `cmd /c/v "..."` 失败——希望它能为你节省 15 分钟 (2认同)
  • @DerekGreer“我想不出任何实际原因”:好的,我已经编辑了答案以添加实际原因。 (2认同)

Vip*_*_Sb 59

您可以在这样的 Windows 中执行此操作,无需安装任何东西。

cmd /C "set EDITOR=vim && set"
Run Code Online (Sandbox Code Playgroud)

你会看到一个变量列表,你会看到 EDITOR=vim,现在再次运行“set”,它不会被列出。

您可以执行多个 && 来添加其他命令:

cmd /C "set EDITOR=vim && do this && do that && otherstuff"
Run Code Online (Sandbox Code Playgroud)

编辑: /C 运行后立即退出新的 cmd,如果您使用新的 cmd 生成输出,它仍将在父窗口中可见。

您可以选择使用 /K,在这种情况下,新的 cmd 窗口在运行结束时保持打开状态。

  • 当心。以这种方式设置变量将导致变量 EDITOR 中出现一个尾随空格:“vim”。为避免尾随空格使用: cmd /C "set "EDITOR=vim" && do this && do that" (9认同)
  • 例如,这不适用于“Windows Server 2008”。我尝试过: set name="username" && echo %username%。并且用户名为空。 (2认同)

小智 11

您可以env在 GnuWin32 http://gnuwin32.sourceforge.net/ 中使用来自 CoreUtils 包的移植 util

  1. 设置它
  2. 检查env.exe%PATH% 变量中存在的目录
  3. 使用与linux版本相同的方式 env EDITOR=vim command

  • 也许值得一提的是,如果您有 git/docker/msys/cygwin,您就已经拥有了它的一个版本。 (2认同)

小智 6

Vonc 的答案适用于将变量引用为扩展的命令(即而!FOO!不是%FOO%

但是,如果您的命令引用常规变量,它将不起作用。

例如考虑:

some-bat.bat(或任何其他可执行文件/批处理进程)

echo %FOO%
Run Code Online (Sandbox Code Playgroud)

以及主要流程:

set FOO=foo
cmd /V /C "set FOO=bar && some-bat.bat"
Run Code Online (Sandbox Code Playgroud)

返回foo而不是bar(但第二次执行会起作用)

但是,您仍然可以连接一个新的 cmd 进程来强制刷新变量。

像这样:

set "FOO=BAR" && cmd /c "echo %FOO%"
Run Code Online (Sandbox Code Playgroud)

或者如果主命令已经必须使用新的 cmd:

cmd /c "set FOO=BAR && cmd /c ^"echo %FOO%^""
Run Code Online (Sandbox Code Playgroud)

  • 非常好的一点。已投赞成票。 (2认同)

AFH*_*AFH 5

我已经创建了一个批处理文件env.cmd,其工作方式或多或少类似于 Linuxenv命令:-

echo off
setlocal
for %%f in (%*) do (
  echo %%f|find "=" >nul:
  if errorlevel 1 goto DoCmd
  set %%f
  shift
)
:DoCmd
%1 %2 %3 %4 %5 %6 %7 %8 %9
endlocal
Run Code Online (Sandbox Code Playgroud)

唯一的区别是,由于cmd解析方式的原因,需要引用环境分配,因此您的命令将是:

env "EDITOR=vim" command [up to 8 parameters]
Run Code Online (Sandbox Code Playgroud)

可以通过在循环内构建命令字符串来详细说明批处理文件以消除 8 个参数的限制for(需要延迟扩展)。

  • @Scott - 因为 `%*` 是_原始_参数列表:它不受 `shift` 的影响(与 Unix 中的 `$*` 不同)。 (3认同)