2010-12-13 19 views
13

Cela doit être quelque chose d'évident, mais je n'arrive pas à le faire fonctionner.powershell: combiner le chemin à l'aide d'une variable

J'essaye de construire une variable qui devrait contenir le chemin vers un fichier existant, en utilisant une variable d'environnement ($ env: programfiles (x86)). Cependant, je continue à avoir des erreurs, et je ne vois pas pourquoi.

Cela fonctionne bien (si le fichier existe):

PS C:\> $f = "C:\Program Files (x86)" + '\sometextfile.txt' 
PS C:\> $f 
C:\Program Files (x86)\sometextfile.txt 
PS C:\> gci $f 
    Directory: C:\Program Files (x86) 
Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---  13/12/2010  14:03   0 sometextfile.txt 
PS C:\> 

Cependant, cela ne signifie pas:

PS C:\> "$env:programfiles(x86)" 
C:\Program Files(x86) 
PS C:\> $f = "$env:ProgramFiles(x86)" + '\sometextfile.txt' 
PS C:\> $f 
C:\Program Files(x86)\sometextfile.txt 
PS C:\> gci $f 
Get-ChildItem : Cannot find path 'C:\Program Files(x86)\sometextfile.txt' because it does not exist. 
At line:1 char:4 
+ gci <<<< $f 
    + CategoryInfo   : ObjectNotFound: (C:\Program Files(x86)\sometextfile.txt:String) [Get-ChildItem], ItemNot 
    FoundException 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand 

Qu'est-ce qui se passe, et comment y remédier?

+1

L'espace manquant dans le deuxième exemple est-il simplement une faute de frappe? "Program Files (x86)" vs "Program Files (x86)" – craika

+0

ce n'est pas, je l'obtiens sans espace aussi. très étrange – CharlesB

+2

non, sur un système 64 bits, vous obtenez deux variables env: $ {env: programfiles} et $ {env: programfiles (x86)} – jeroenh

Répondre

20

Voici ce qui se passe ...

Dans tous les caractères ou espaces vides de chemin Windows Powershell doivent être entouré d'un ensemble de citations ou entre parenthèses. La variable d'environnement Powershell pour les fichiers C: \ Program (x86) est ${env:ProgramFiles(x86)} et non $env:ProgamFiles(x86) puisque Powershell doit échapper aux espaces vides dans le chemin réel.

Si vous utilisez la variable d'environnement explicite '$ {env: ProgramFiles (x86)}', cela fonctionne parfaitement.


Cela ne fonctionnera pas ...

PS C:\> cd "$env:programfiles(x86)" 
Set-Location : Cannot find path 'C:\Program Files(x86)' because it does not e 
At line:1 char:3 
+ cd <<<< "$env:programfiles(x86)" 
+ CategoryInfo   : ObjectNotFound: (C:\(x86):String) 
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell. 

ou cette ....

PS C:\> $env:ProgramFiles(x86) 
Unexpected token '(' in expression or statement. 
At line:1 char:19 
+ $env:ProgramFiles(<<<< x86) 
+ CategoryInfo   : ParserError: ((:String) [], Parent 
+ FullyQualifiedErrorId : UnexpectedToken 

Mais cela fonctionne très bien ....

PS C:\> ${env:ProgramFiles(x86)} 
C:\Program Files (x86) 
PS C:\> $f = "${env:ProgramFiles(x86)}" + "\sometextfile.txt" 
PS C:\> $f 
C:\Program Files (x86)\sometextfile.txt 
PS C:\> gci $f 
Directory: C:\Program Files (x86) 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---  12/13/2010 8:58 AM   0 sometextfile.txt 

Espérons que cela aide!

~ Dan

+5

Par l'affiche précédente, ce n'est pas un bug. Dans la syntaxe Powershell, les parenthèses indiquent un paramètre qui est transmis à une cmdlet ou un script. Étant donné que la variable d'environnement stocke un chemin avec un ensemble de parenthèses, la variable doit être échappée et évaluée entre $ {}. Pour voir ce que je veux dire, essayez de faire une variable avec des parenthèses, par exemple $ dogs (areawesome) ou $ programs (x64) et vous obtiendrez un 'token inattendu' ('in expression ou statement.) Les codeurs Powershell auraient pu éviter ce problème en faisant la variable d'environnement "$ env: ProgramFilesx86". – thoughtpunch

+0

bonne explication, merci – jeroenh

+4

Votre réponse est correcte, mais la raison ne l'est pas. Un espace dans le chemin résultant n'a rien à voir avec la raison pour laquelle cet envvar particulier nécessite '{}'. Si c'est le cas, alors $ env: ProgramFiles nécessitera aussi {{} 'mais ce n'est pas le cas. La raison pour laquelle ProgramFiles (x86) se comporte mal est purement un problème de parseur. Lorsque l'analyseur évalue '$ env: ProgramFiles (x86)', il voit une nouvelle expression 'Group' quand il voit l'ouverture des parens qui n'est pas valide étant donné le contexte actuel. Vous pouvez le voir avec le tokenizer PowerShell, par exemple: '[management.automation.psparser] :: Tokenize ('$ env: ProgramFiles (x86)', [ref] $ erreurs)'. –

1

C'est bizarre. On dirait un bug. Ce qu'il est en train de faire, c'est de résoudre la variable $ env: programfiles et d'ajouter le reste de la chaîne - ce qui dans ce cas se trouve être (x86).

Cela fonctionne bien:

$f = ${env:ProgramFiles(x86)} + '\sometextfile.txt'