大佬教程收集整理的这篇文章主要介绍了如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在 CMD 脚本文件中使用以下代码
PowerSHell add-type -Assemblyname System.windows.Forms;^
$line_1 = 'Hello!';^
$line_2 = 'How are you?';^
[System.windows.Forms.messageBox]::Show($line_1)
以上只会显示($line_1)
如果使用 ($line_1`n$line_2)
,则不会显示任何内容。
如何让它同时显示$line_1
和$line_2
?
最简单的解决方案是(注意 \"$Line_1`n$Line_2\"
部分):
PowerSHell -c Add-Type -AssemblyName System.Windows.Forms; ^
$Line_1 = 'Hello!'; ^
$Line_2 = 'How are you?'; ^
[System.Windows.Forms.messageBox]::Show(\"$Line_1`n$Line_2\")
请注意,我已明确添加了 -c
(-Command
) 参数名称以表示正在传递 PowerSHell 命令字符串。虽然这在 Windows PowerSHell 中不是必需的,默认为 -Command
,但在 PowerSHell (CorE) 7+ 中,-File
是现在是默认设置 - 请参阅 Windows PowerSHell 和 PowerSHell (CorE) 7+ 的 CLI 文档。
也就是说,您必须在 $Line_1`n$Line_2
中使用 "..."
,一个 expandable String,并且您必须\
-转义 { {1}} 个字符,以便 PowerSHell 不会将它们作为其命令行解析的一部分剥离(在没有整体双引号的情况下,"
也可以使用) .
不幸的是,解析规则在使用 for /f
时改变,以便逐行处理 PowerSHell 的输出和/或将其捕获到变量中:
注意:下面使用 """
来生成控制台输出,只是为了使用与 [Console]::WriteLine()
方法调用类似的语法,同时允许 {{1} 捕获某些内容}}。在现实生活中,没有很好的理由调用 [System.Windows.Forms.messageBox]::Show()
。
for /f
[Console]::WriteLine()
必须另外被转义(在 for /f "delims=" %%l in ('
PowerSHell -c Add-Type -AssemblyName System.Windows.Forms^; ^
$Line_1 ^= 'Hello!'^; ^
$Line_2 ^= 'How are you?'^; ^
[Console]::WriteLine^(\"$Line_1`n$Line_2\"^)
') do echo [%%l]
所看到的 =,; ( )
字符串之外)。
如果您另外在 cmd.exe
中包含一个 "..."
字符串以防止空格规范化(请参阅下一节)和该字符串则需要 \"...\"
-转义嵌入的 "..."
元字符,您必须莫名其妙地在 initial ^
前面加上 cmd.exe
;例如,"
换行符(位于命令内部行末尾的 ^
)实际上在 ^"\"Marley ^& Me\""
中是可选的,但为了一致性而将它们包含在内。 >
引用和转义要求摘要:
带有续行的多行技术(行尾的 ^
) - 在语法上不能使用 for /f
引用整个 命令,因为 ^
不支持双引号多行 Strings - 需要小心的 "..."
-转义所有 cmd.exe
元字符,应该传递给PowerSHell,特别是^
,此外,如果从cmd.exe
语句中调用PowerSHell,& | < > ^
- 除非这些字符碰巧是 for /f
视为 double 引用的子字符串的一部分;例如,放置在 ,; = ( )
字符串内的 cmd.exe
- 例如&
- 必须不能被 \"...\"
-escaped(但见下文关于空白规范化)。
每个语句都必须以 for /f
结尾(正如您所做的那样),因为换行符 (^
) 导致输入之间没有 换行符行,因此 PowerSHell 将它们视为一行,多个语句必须以 ;
分隔。
因为 ^
和 PowerSHell 的 initial 命令行解析都不知道单引号字符串 (;
) 并且因为 转义 cmd.exe
字符串中的 '...'
字符在命令行解析过程中没有 语法 功能,如果这些字符串包含空格,则会被分解为 多个 参数:
实际上,这些字符串中多个相邻空格的运行被标准化为每个单个空格。例如,"
和 \"...\"
最终被 PowerSHell 视为 'How are you?'
和 \"How are you?\"
。
为避免这种情况,另外将这些字符串括在未转义 'How are you?'
中(如果 em>整个命令包含在 "How are you?"
) 中:"
和 "..."
。
PowerSHell 最终应将其视为 "'How are you?'"
(插值)字符串,但棘手的部分是 "\"How are you?\""
无法识别 "..."
-转义 cmd.exe
字符,因此 it 将 \
视为双引号字符串 ("
),后跟一个不带引号的字符串 ("\"How are you?\""
),后跟另一个双引号字符串 ("\"
)。因此,此类字符串中的任何 How are you?\
元字符都必须再次进行 ""
转义才能传递到 PowerSHell(这不适用于包装的 cmd.exe
字符串,例如 ^
);例如:'...'
PowerSHell 如何解析传递给其 CLI 的 "..."
/ """How are you?"""
参数的参数:
PowerSHell 为您提供传递命令字符串之间的选择
either:作为单个参数,包含在整体-Command
中;例如:
-c
或:多个 参数 - 可能单独使用 "..."
引用 - 然后 PowerSHell 将这些参数连接起来形成一个字符串;例如:
powersHell -c "Get-Date -Format 'yyyy MMM'"
在这两种情况下,未转义 "..."
个字符都从参数中剥离,因为为了命令行 而不是生成的 PowerSHell 命令。
剥离语法 powersHell -c Get-Date -Format "'yyyy MMM'"
字符并用空格连接结果参数后(如果适用),PowersHell 将结果字符串解释为 PowerSHell 代码。
注意:这与您使用 "
CLI 参数调用 脚本文件 并将参数传递给它时解析参数的方式有根本的不同 - 有关更多信息,请参阅 this answer .
显然 $Line_1 + "`n" + $Line_2
和 "$Line_1`n$Line_2"
工作正常。将命令字符串从 cmd 发送到 PowerSHell 非常棘手,因为它具有传统的怪癖:
()
中,不同地方的特殊字符表示一个块<space>
和 <tab>
,还有 ;
,
=
<0x0B>
<0x0C>
and <0xFF>
。这会更改 cmd 的标记化行为,但被调用的命令可能会再次使用其规则重新解析命令根据文档,PowerSHell 期望最后一个参数中的单个字符串中的命令(这并不完全正确,因为文档没有正确更新),所以你需要引用整个内容或转义所有的分隔符。最简单的解决方案是使用单行并像这样转义 "`n"
中的引号
PowerSHell "Add-Type -AssemblyName System.Windows.Forms; $Line_1 = 'Hello!'; $Line_2 = 'How are you?'; [System.Windows.Forms.messageBox]::Show($Line_1 + \"`n\" + $Line_2)"
如果您想将命令放在多行中,则不能引用字符串。要将整个内容作为单个参数,现在您需要转义所有空格(在这种情况下您不需要转义 ;
,可能是因为在将命令行传递给 PowerSHell 后,它会调用 {{ 1}} 并再次解析整个事情本身)
GetCommandLineW
或者,您可以通过直接使用 PowerSHell Add-Type^ -AssemblyName^ System.Windows.Forms;^
$Line_1^ =^ 'Hello!';^
$Line_2^ =^ 'How^ are^ you?';^
[Windows.Forms.messageBox]::Show($Line_1^ +^ \"`n\"^ +^ $Line_2)"
获取新行来避免使用 "`n"
字符串
[char]10
最后一个无需任何转义即可工作的解决方案,它利用 PowerSHell 的 PowerSHell -Command Add-Type -AssemblyName System.Windows.Forms;^
$Line_1 = 'Hello!';^
$Line_2 = 'How are you?';^
[System.Windows.Forms.messageBox]::Show($Line_1 + [char]10 + $Line_2)
选项接收 UTF-16 命令字符串的 base64 编码字符串。您可以通过在 PowerSHell 中运行它来获取编码版本
EncodedCommand
获得编码版本后,您可以从 cmd 调用它
$str = @'
>> Add-Type -AssemblyName System.Windows.Forms;
>> $Line_1 = 'Hello!';
>> $Line_2 = 'How are you?';
>> [System.Windows.Forms.messageBox]::Show($Line_1 + "`n" + $Line_2)
>> '@
PS C:\Users\phucl> [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($str))
QQBkAGQALQBUAHkAcABlACAALQBBAHMAcwBlAG0AYgBsAHkATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVwBpAG4AZABvAHcAcwAuAEYAbwByAG0AcwA7AAoAIAA9ACAAJwBIAGUAbABsAG8AIQAnADsACgAgAD0AIAAnAEgAbwB3ACAAYQByAGUAIAB5AG8AdQA/ACcAOwAKAFsAUwB5AHMAdABlAG0ALgBXAGkAbgBkAG8AdwBzAC4ARgBvAHIAbQBzAC4ATQBlAHMAcwBhAGcAZQBCAG8AeABdADoAOgBTAGgAbwB3ACgAIAArACAAIgAKACIAIAArACAAKQA=
,
有多种连接字符串的方法可以查找,但最简单的方法可能是使用 + 符号。 `n 是一个换行符,它将第 2 行置于第 1 行下方。请注意,` 是一个反引号(通常与波浪号 ~ 位于同一键上)
[System.Windows.Forms.messageBox]::Show($Line_1 + "`n" + $Line_2)
再次查看您的帖子后,我注意到您与 ($Line_1`n$Line_2) 很接近。你只是缺少一些双引号
[System.Windows.Forms.messageBox]::Show("$Line_1`n$Line_2")
PowersHell 很乐意将变量放在双引号内时替换它们的值。您可以阅读有关可扩展字符串 here 和 here
的更多信息以上是大佬教程为你收集整理的如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?全部内容,希望文章能够帮你解决如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。