2013-04-10 16 views
6

C'è qualcosa di veramente strano in questa lingua. Sto cercando di eseguire una funzione e utilizzare il suo valore di risultato come condizione. Questo è il mio codice:Condizione con una chiamata di funzione in PowerShell

function Get-Platform() 
{ 
    # Determine current Windows architecture (32/64 bit) 
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null) 
    { 
     echo "x64" 
     return "x64" 
    } 
    else 
    { 
     echo "x86" 
     return "x86" 
    } 
} 

if (Get-Platform -eq "x64") 
{ 
    echo "64 bit platform" 
} 
if (Get-Platform -eq "x86") 
{ 
    echo "32 bit platform" 
} 

Il risultato atteso è questo:

x64 
64 bit platform 

Ma l'uscita effettiva è questo:

64 bit platform 
32 bit platform 

cosa sta succedendo qui? Come si puo aggiustare? Non sono riuscito a trovare alcun esempio sul web che utilizzi funzioni all'interno di una condizione if. E 'possibile a Powershell? Sono su Windows 7 senza configurazioni speciali, quindi ho la versione PS che viene con esso.

risposta

16

Se si desidera confrontare il valore di ritorno di una funzione in un condizionale, è necessario gruppo la chiamata di funzione (cioè metterlo in parentesi) o (come @FlorianGerhardt suggerito) assegnare il valore di ritorno della funzione a una variabile e utilizzare tale variabile nel condizionale. Altrimenti l'operatore di confronto e l'altro operando sarebbero passati come argomenti alla funzione (dove nel tuo caso vengono scartati silenziosamente). La funzione restituisce quindi un risultato che non è né ""0$null, quindi viene valutato su $true, provocando la visualizzazione di entrambi i messaggi.

Questo dovrebbe fare quello che vuoi:

... 
if ((Get-Platform) -eq 'x64') { 
    echo "64 bit platform" 
} 
... 

BTW, si dovrebbe evitare di utilizzare separati if dichiarazioni per le condizioni che si escludono a vicenda. Per una piattaforma di controllare un if..then..elseif

$platform = Get-Platform 
if ($platform -eq "x64") { 
    ... 
} elseif ($platform -eq "x86") { 
    ... 
} 

o un switch dichiarazione

Switch (Get-Platform) { 
    "x86" { ... } 
    "x64" { ... } 
} 

sarebbe più appropriato.

Eviterei anche di echo all'interno della funzione. Basta restituire il valore e fare qualsiasi eco che potrebbe essere richiesto con il valore restituito. Tutto ciò che viene ripreso all'interno della funzione verrà anche restituito al chiamante.

Un'ultima nota: personalmente preferirei non fare affidamento sull'esistenza di una particolare cartella o variabile d'ambiente per determinare l'architettura del sistema operativo. Utilizzando WMI per questo compito mi ritiene molto più affidabile:

function Get-Platform { 
    return (gwmi Win32_OperatingSystem).OSArchitecture 
} 

Questa funzione restituisce una stringa "32-Bit" o "64-Bit", a seconda dell'architettura del sistema operativo.

+0

Grazie per la spiegazione completa. Usare parentesi attorno al nome della funzione sembra davvero chiamare la funzione, quindi questa sembra una soluzione universale a tali problemi. Molto più semplice dell'utilizzo di un altro nome di variabile per questo. L'eco nella funzione (sostituito da un host di scrittura per essere funzionale) è solo a scopo di traccia. Questo è uno script di testcase. Anche se ora vedo il seguente output: "x64", "64 bit platform", "x64". La chiamata WMI sembra restituire una stringa localizzata, per me è "64 bit". L'altro assegno è ampiamente utilizzato altrove, a quanto pare. – ygoe

+0

'OSArchitecture' restituisce una stringa' "32-Bit" 'o' "64-Bit" ', a seconda dell'architettura del SO, quindi dovresti adattare le condizioni a quello. –

3

Penso che si stia confrontando una funzione e non il risultato della funzione. Inoltre, in qualche modo l'eco non funziona come previsto in una funzione. Di solito uso Write-Host.

Qui è la mia soluzione al vostro problema:

function Get-Platform() 
{ 
    # Determine current Windows architecture (32/64 bit) 
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null) 
    { 
     Write-Host("x64") 
     return "x64" 
    } 
    else 
    { 
     Write-Host("x86") 
     return "x86" 
    } 
} 

$platform = Get-Platform 

if ($platform -eq 'x64') 
{ 
    echo "64 bit platform" 
} 

if ($platform -eq 'x86') 
{ 
    echo "32 bit platform" 
} 
Problemi correlati