AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79586751
Accepted
Maarten ten Velden
Maarten ten Velden
Asked: 2025-04-22 22:43:41 +0800 CST2025-04-22 22:43:41 +0800 CST 2025-04-22 22:43:41 +0800 CST

在批处理文件中保留引号 %*

  • 772

我想%*从批处理脚本转发到 Powershell 脚本,这已经可以正常工作了。唯一的问题是我无法干净地转发带有空格的参数。

示例.bat..

@echo off

set cwd=%~dp0
set argv=%*
powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%Example.ps1' %argv%"

示例.ps1..

Param(
  $Message
)
If (!$Message)
{
  $Message = "Hello!!!"
}
Write-Host $Message

我可以做得./Example.bat Oh很好,打印出来Oh。但是,./Example.bat "Oh no"也只能打印出来Oh。./Example "'Oh no'"虽然可以工作,但并不干净,因为脚本的使用不再相同,这意味着对它的任何使用都会变得紧密耦合,而这是我不想要的。

powershell
  • 4 4 个回答
  • 109 Views

4 个回答

  • Voted
  1. Fabrice SANGA
    2025-04-22T23:49:20+08:002025-04-22T23:49:20+08:00

    在批处理文件中嵌入 PowerShell 命令时,应格外小心地正确转义双引号。将整个 PowerShell 命令括在双引号中后,必须将后续的双引号字符转换"为 \"

    这是更正后的Example.bat脚本:

    @echo off
    
    set cwd=%~dp0
    set argv=_%*
    set argv=%argv:"=\"%
    set argv=%argv:~1%
    powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%Example.ps1' %argv%"
    

    不要对我进行转义所经历的额外步骤感到困惑。set argv=%argv:"=\"%是唯一强制性的步骤,其他行确保空字符串(无参数)也得到正确处理。

    用户可能认为使用插入符号^就足以转义输入字符串中的特殊字符,如下所示"You ^& ^| ^> ^< ^^ I"

    > Example.bat "You ^& ^| ^> ^< ^^ I"
    You & | > < ^ I
    

    如果用户想要输入不带转义符号的特殊字符,更完整的解决方案如下:

    正如 注释 所建议的,我们可以通过为命令提示符解释器转义其他特殊字符来扩展解决方案。我们还可以添加双引号来转义符号。(为了清晰起见,我没有使用该for命令)

    @echo off
    
    set cwd=%~dp0
    set argv=_%*
    set argv=%argv:^=^^%
    set argv=%argv:"=\"%
    set argv=%argv:\"\"=`\"%
    set argv=%argv:&=^&%
    set argv=%argv:|=^|%
    set argv=%argv:>=^>%
    set argv=%argv:<=^<%
    set argv=%argv:~1%
    powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%Example.ps1' %argv%"
    

    然后,我们可以执行以下操作:

    > Example.bat """You"" & | > < ^ I"
    "You" & | > < ^ I
    
    • 3
  2. Best Answer
    mklement0
    2025-04-23T03:48:46+08:002025-04-23T03:48:46+08:00

    Fabrice SANGA 的有用答案解释了转义字符的必要性"。嵌入得 %*很好,并提供了一种通常有效的解决方案,即使用\"转义。

    然而,它并不健壮,因为它会破坏包含元字符(如或)的封闭参数cmd.exe的解析,例如"..."cmd.exe&|"you & I"

    更新:链接的答案已经更新为尝试提供强大解决方案的替代解决方案,但下面的解决方案更简单。

    一个强大的解决方案需要一种不同的 - 模糊的 -转义嵌入 "字符的形式。,即 as"^"" [sic] 而不是 as\"

    • 注意:这适用于powershell.exeWindows PowerShell CLI;对于pwsh.exePowerShell (Core) 7 CLI,请使用""

    这是一个强大而精简的解决方案,它同样使用这种转义形式来括住目标*.ps1路径,以便'正确处理带有嵌入字符的路径。
    另请注意,使用了%~dpn0.ps1,这样就无需重复基本文件名了Example:

    @echo off & setlocal
    
    :: Escape any " chars. embedded in %* as "^""
    set argv=%*
    if defined argv set argv=%argv:"="^""%
    
    powershell -NoProfile -ExecutionPolicy Bypass -Command "& "^""%~dpn0.ps1"^"" %argv%"
    

    setlocal用于确保批处理文件中定义的变量作用域于该文件;默认情况下,它们将被全局定义。

    向João Mac 的回答致敬,他提醒我们,该if defined somevar技术可以作为变量空性/不存在性测试,这比if not %somevar%.==.


    退一步来说:

    如果您的目的仅仅是调用*.ps1带有参数的文件,则最好使用-File( -f)CLI参数而不是-Command( -c)

    这样做有两个好处:

    • 它消除了转义的需要,因此大大简化了批处理文件(见下文)。

    • 它可以保护您的参数免受 PowerShell 的潜在有害解释:例如,使用 时-File,将按$HOME原样传递参数,而使用 时,-Command它将扩展为 PowerShell 的自动$HOME变量。

    @echo off & setlocal
    
    powershell -NoProfile -ExecutionPolicy Bypass -File "%~dpn0.ps1" %*
    

    有关何时使用-Filevs. 的详细指导-Command,请参阅此答案。

    • 3
  3. João Mac
    2025-04-23T00:31:24+08:002025-04-23T00:31:24+08:00

    在这种特定情况下,无需使用,%*因为目的是仅获取传递给批次的第一个参数,而不是所有参数。

    我建议的Example.bat脚本如下:

    @echo off
    
    set appfolder=%~dp0
    set argv=%1
    if defined argv set argv=%argv:"="^""%
    pushd "%appfolder%"
    powershell -NoProfile -ExecutionPolicy Bypass -Command "& .\Example.ps1 %argv%"
    popd
    

    该解决方案考虑了 Compo 的评论和 SANGA 的转义和空参数观察。

    编辑1:

    重要的是不要忘记之前所写的内容。该规范是一项提案,旨在服务于各种用途,从标准温度和压力(STP)条件下的使用,到混合战争中的使用。

    有一些策略可以在包含特殊字符的文件夹中执行批处理。我使用pushd和popd。因此,代码提案已修改,以符合 Mofi 评论的第一部分。

    已经是评论的第二部分,使用以下命令行(带提示):

    D:\Usuários\Botafogo> "D:\Temp\teste\botafogo é campeão — desenvolvimento e teste 100% (!) com 'nome feio' e `nome bonito` bênção よろしくお願いいたします。\example.bat" "Hello world! & Does that work? See the second edition. ;) 😉"

    至于用BAT文件召唤文件PS1,我只是尝试按照原始消息请求操作。我只是请求你不要把我当成敌人,而要把我当成一个愿意帮助别人的人。

    编辑2:

    根据 mklement0 的回答来使用metacharacters(通过转义"为)。"^""

    我使用了在线翻译。抱歉,我的语言不太流利。

    • 1
  4. Magoo
    2025-04-23T18:33:22+08:002025-04-23T18:33:22+08:00

    我有点不明白这个练习的目的。

    powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%q79586751.ps1' '%argv:"=\"%'"
    

    根据我对原始问题的理解,这对我来说似乎“有效”,但我确信它不会对其他一些符号“起作用”,这些符号可能重要也可能不重要,这取决于所提供的参数是否符合建议(,,Oh)或是否有望被普遍逐字复制。Oh no"Oh no"

    (我重命名了该.ps1文件,因为我希望将所有响应数据都保存在 SO 问题编号下)

    • 0

相关问题

  • 如何获取作业的进程句柄?

  • PowerShell 一行代码 - 如何

  • Powershell 5.1:我的模块中缺少别名描述

  • Import-CSV:将行(成员)添加到 foreach 循环中的结果对象

  • 在所有startthreadjob powershell中使用和修改我的变量

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve