【问题标题】:How can I write/create a powershell script verbatim, from another powershell script?如何从另一个 powershell 脚本逐字编写/创建 powershell 脚本?
【发布时间】:2019-08-31 21:35:21
【问题描述】:

以下代码(在底部)在文件中产生以下输出之一

4/12/2019 = (get-date).AddDays(2).ToShortDateString();
4/13/2019 = (get-date).AddDays(2 + 1).ToShortDateString();

或者如果我没有初始化变量

 = (get-date).AddDays(2).ToShortDateString();
 = (get-date).AddDays(2 + 1).ToShortDateString();

这是代码块,我希望父ps1文件逐字写入子ps1文件。

$multiLineScript2 = @"

    $startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
    $endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();
"@

$multiLineScript2 | Out-File "c:\file2.ps1";

【问题讨论】:

  • 对此处的字符串(不是脚本块)使用单引号以扩展变量 NOT

标签: powershell


【解决方案1】:

tl;dr

要创建一个逐字多行字符串(即,具有文字内容的字符串),请使用a 单引号这里的字符串

$multiLineScript2 = @'

    $startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
    $endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();
'@

注意使用@''@ 作为分隔符。

仅当需要字符串扩展(插值)时才使用双引号选择性地抑制扩展,转义$字符。以`$的形式逐字包含在内,如your own answer所示。


PowerShell 中的字符串文字

Get-Help about_quoting rules 讨论 PowerShell 支持的字符串文字类型

  • 要获得具有 literal 内容 的 字符串(没有插值,C# 将其称为 verbatim 字符串),请使用 单引号'...'

    • 嵌入' 字符。在 '...' 字符串中,double 它们('');所有其他字符。可以按原样使用。
  • 获得一个可扩展字符串(字符串插值),即一个包含变量引用(例如$var${var})和表达式(例如, $($var.Name)) 可以嵌入替换为它们的值,使用 双引号"..."

    • 要选择性地抑制扩展,反引号-escape $ chars.;例如,为了防止 $var"..." 字符串中插入(扩展为其值),请使用 `$var;要嵌入文字反引号,请使用 ``
    • 有关字符串扩展规则的概述,请参阅this answer

这两种基本类型也可以作为 here-strings - 分别以 @'<newline>...<newline>'@@"<newline>...<newline>"@ 的形式提供(<newline> 代表实际的换行符(行break)) - 使定义多行字符串更容易

  • 重要
    • 开头分隔符之后没有任何内容(除了空格) - @'@" - 在同一行 - 字符串的内容必须在以下中定义行。
    • 结束定界符 - '@"@(与开始定界符匹配) - 必须位于一行的开头
    • 在文件中定义的此处字符串总是使用其封闭文件的换行符格式(CRLF vs. LF),而交互式定义的总是只使用LF。李>

例子:

# Single-quoted: literal:
PS> 'I am $HOME'
I am $HOME

# Double-quoted: expandable
PS> "I am $HOME"
I am C:\Users\jdoe

# Here-strings:

# Literal
PS> @'
I am
  $HOME
'@
I am
  $HOME

# Expandable
PS> @"
I am
  $HOME
"@
I am
  C:\Users\jdoe

【讨论】:

    【解决方案2】:

    我在任何地方都找不到这个,但似乎脚本中的每个变量(字符串文字)都必须像这样用勾号转义。我不会删除问题,而是将其留待搜索。

    $multiLineScript2 = @"
    
    `$startDate2 = (get-date).AddDays($resultOfSubtraction).ToShortDateString();
    `$endDate2 = (get-date).AddDays($resultOfSubtraction + 1).ToShortDateString();
    
    "@
    

    【讨论】:

    • 正如@LotPings 前面所述,将您的此处字符串更改为使用@' '@ 而不是@" "@。那么你就不需要转义变量了。
    • @AdminOfThings 看起来 OP 想要扩展一些 ($resultOfSubtraction),但不是所有变量。
    • 正如 PetSerAl 所说,似乎 选择性 抑制扩展(插值)是目标,这使得“脚本中的每个变量”这个短语令人困惑。使用双引号此处字符串 (@"<newline>...<newline>"@) 开头的唯一充分理由是,如果至少需要 一些 扩展。
    最近更新 更多