2010-12-13 24 views
13

Questo deve essere una cosa ovvia, ma non riesco a farlo funzionare.PowerShell: combinando percorso utilizzando una variabile

Sto cercando di costruire una variabile che dovrebbe contenere il percorso di un file esistente, utilizzando una variabile d'ambiente ($ env: Programmi (x86)). Tuttavia continuo a ricevere errori e non riesco a capire perché.

Questo funziona bene (se il file esiste):

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:\> 

Tuttavia, questo non lo fa:

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 

Che cosa sta succedendo, e come risolvere il problema?

+1

Lo spazio mancante nel secondo esempio è solo un errore di battitura? "Program Files (x86)" vs "Program Files (x86)" – craika

+0

non lo è, ho capito anche senza spazio. molto strano – CharlesB

+2

no, su un sistema a 64 bit si ottengono due variabili env: $ {env: programfiles} e $ {env: programfiles (x86)} – jeroenh

risposta

20

Ecco cosa sta succedendo ...

in qualsiasi percorso di Windows PowerShell caratteri vuoti o spazi hanno bisogno di essere circondato da una serie di citazioni o staffe. La variabile di ambiente PowerShell per il C: \ Program Files (x86) è ${env:ProgramFiles(x86)} non $env:ProgamFiles(x86) dal PowerShell deve sfuggire gli spazi vuoti nel percorso reale.

Se si utilizza il '$ {ENV: ProgramFiles (x86)}' variabile ambiente esplicito, funziona perfettamente.


Questo non funziona ...

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. 

o questa ....

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 

Ma questo funziona alla grande ....

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 

Spero che questo aiuti!

~ Dan

+5

Per il poster precedente, questo non è un bug. Nella sintassi di PowerShell, le parentesi indicano un parametro che viene passato a un cmdlet o script. Poiché la variabile di ambiente memorizza un percorso ha una serie di parentesi al suo interno, la variabile deve essere sottoposta a escape e valutata tra $ {}. Per vedere cosa intendo, prova a creare una variabile con parentesi al suo interno, ad esempio $ dogs (areawesome) o $ programs (x64) e otterrai un 'Inaspettato token' ('in espressione o istruzione. I codificatori di Powershell avrebbero potuto evitare questo problema rendendo la variabile di ambiente "$ env: ProgramFilesx86". – thoughtpunch

+0

grande spiegazione, grazie – jeroenh

+4

La tua risposta è corretta ma il motivo non lo è. Uno spazio nel percorso risultante non ha nulla a che fare con il motivo per cui questo particolare envvar richiede '{}'. Se fosse così, allora '$ env: ProgramFiles' richiederebbe anche' {} 'ma non è così. La ragione per cui ProgramFiles (x86) si comporta male è puramente un problema di parser. Poiché il parser valuta '$ env: ProgramFiles (x86)', vede una nuova espressione 'Gruppo' quando vede i parents di apertura che non sono validi dato il contesto corrente. Puoi vederlo con il tokenizzatore di PowerShell per esempio: '[management.automation.psparser] :: Tokenize ('$ env: ProgramFiles (x86)', [ref] $ errori)'. –

1

Questo è strano. Sembra un insetto. Quello che sta facendo in realtà sta risolvendo la variabile $ env: programfiles e aggiungendo il resto della stringa - che in questo caso sembra essere (x86).

Ciò funzionerà se:

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