web-dev-qa-db-fra.com

Que signifie $ ($ variableName) dans les chaînes extensibles dans PowerShell?

J'ai vu un certain nombre d'exemples de scripts en ligne qui utilisent cela. Plus récemment, je l'ai vu dans un script sur automatisation de TFS :

[string] $fields = "Title=$($taskTitle);Description=$($taskTitle);Assigned To=$($assignee);"
$fields += "Area Path=$($areaPath);Iteration Path=$($iterationPath);Discipline=$($taskDisciplineArray[$i]);Priority=$($i+1);"
$fields += "Estimate=$($taskEstimateArray[$i]);Remaining Work=$($taskRemainingArray[$i]);Completed Work=$($tasktaskCompletedArray[$i])"

D'après ce que je peux dire, $($taskTitle) semble être équivalent à $taskTitle. Suis-je en train de manquer quelque chose? Y a-t-il une raison d'utiliser les parenthèses et le signe dollar supplémentaire?

29
KevinD

La syntaxe aide à évaluer l'expression à l'intérieur.

$arr = @(1,2,3)

$msg1 = "$arr.length"
echo $msg1 # prints 1 2 3.length - .length was treated as part of the string

$msg2 = "$($arr.length)"
echo $msg2 # prints 3

Vous pouvez en savoir plus sur http://ss64.com/ps/syntax-operators.html

33
Amith George

Pour compléter réponse utile d'Amith George avec plus d'informations générales :

D'après ce que je peux dire, $($taskTitle) semble être équivalent à $taskTitle.

En effet, dans le contexte de "...", Une chaîne extensible (chaîne d'interpolation):

  • Vous n'avez PAS besoin de $(...) avec simple référence de variable tel que $taskTitle ou $env:HOME

    • Parfois, vous devez (ou pouvez choisir) utiliser le formulaire ${taskTitle} Ou ${env:HOME} - c'est-à-dire {...} Autour de l'identifiant - afin de lever l'ambiguïté du nom de la variable à partir des caractères suivants dans le chaîne.
  • Vous avez besoin de $(...) pour toute autre chose:

    • accéder à une propriété; par exemple.:
      "count is: $($var.Count)"
    • incorporer un expression; par exemple.:
      "path prefix: $($var + '/')"
    • incorporer des commandes entières (éventuellement même plusieurs celles-ci); par exemple.:
      "file names: $(Get-ChildItem *.txt | Select-Object -ExpandProperty Name)"

En bref:

  • $(...) à l'intérieur de "..." est nécessaire pour autre chose que de simples références de variable et vous permet d'incorporer des instructions à l'intérieur de "..."; comme d'habitude, lorsque la chaîne est évaluée, la partie $(...) est remplacée par la (stringified) output ​​de la ou des instructions incorporées.

  • Si vous ne voulez pas penser quand $(...) est et n'est pas nécessaire, vous pouvez choisir toujours de l'utiliser (par exemple, $($taskTitle)), mais notez que c'est lourd à taper et visuellement "bruyant".

    • Avertissement : il y a un cas Edge où le comportement de $($var) est pas identique à celui de $var/${var}, à savoir si $var est un - collection (implémentant [System.Collections.IEnumerable]) qui ne contient qu'un élément unique - voir les commentaires de PetSerAl ci-dessous.
  • À moins que la valeur de la variable référencée/de l'instruction incorporée ne soit déjà une chaîne, elle est chaîne à l'aide de la fonction .NET .ToString() méthode , avec la torsion notable que les types qui prennent en charge culture-sensitive stringification sont stringifiés avec culture invariante, qui, en gros, ressemble au format anglais américain; par exemple, "$(1.2)"toujours donne 1.2, même dans les cultures où , est la marque décimale; voir cette réponse à moi pour en savoir plus.

Documentation :

Le nom officiel de $(...) est opérateur de sous-expression, comme (laconiquement) documenté dans Get-Help about_Operators , bien que l'explication ne traite pas de l'utilisation spécifique de l'opérateur dans le contexte des chaînes extensibles.

Inversement, Get-Help about_Quoting_Rules , qui traite des littéraux de chaîne, y compris les chaînes extensibles, montre exemples de $(...) à utiliser uniquement dans le contexte des chaînes extensibles.

10
mklement0