Powershell Command Processing (Passerer i variabler)

stemmer
7

Jeg oppretter en Powershell script for å distribuere noen kode og en del av prosessen er å ringe et kommandolinje komprimering verktøy kalt rar.exe å sikkerhetskopiere noen mapper.

Jeg forsøker å dynamisk bygge ut parametrene og så har Powershell kaller kommandoen med variablene, men jeg kjører i trøbbel. Det virker ikke ...

Kjør følgende script og du skal se hva jeg snakker om. Parametrene som føres inn som en variabel blir revet i stykker. Hvis jeg passerer hele kommandoen + parametere jeg får den beryktede gjenkjennes ikke som en cmdlet ... -melding.

Takk for hjelp!

echo this should succeed
& cmd /c echo foo

echo why does this echo out an additional double quote?
$param = /c echo foo
& cmd $param

echo this does the same
$param = /c echo foo
& cmd $param

echo escaping the slash doesn't work either...
$param = `/c echo foo
& cmd $param

echo this fails, but why?
$cmd = cmd /c echo foo
&$cmd
Publisert på 30/04/2009 klokken 22:04
kilden bruker
På andre språk...                            


6 svar

stemmer
0

det er en gjenstand for å bruke cmd / c, tror jeg. løping

$param = "echo foo"
cmd /c $param

fungerer fint. Med mindre du har en reell kode eksempel, er det litt vanskelig å skyte problemer.

Svarte 01/05/2009 kl. 00:00
kilden bruker

stemmer
7

Jeg har hatt problemer med og samtale operatør i det siste når jeg prøver å påberope kjør typen kommandoer som du prøver. Ikke at jeg forstår hvorfor. Påkall-Expression imidlertid alltid synes å fungere i denne sammenheng:

PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo
Svarte 01/05/2009 kl. 01:15
kilden bruker

stemmer
3

Ditt siste eksempel hvis sviktende fordi "&" behandler strengen som ett argument, så det er på utkikk etter et program som heter "cmd / c ekko foo.exe". :)

Dette fungerer:

& $cmd $params

Som for dobbel sitat problemet, gjør det virke som cmd ikke liker anførselstegn rundt argumenter som Powershell setter. Det blir denne:

cmd "/c echo foo"

Så jeg tror det behandler alt etter / c som nøyaktig kommando, så som så:

echo foo"

Noen kommandolinjeprogrammer og funky analyseringen av kommandolinjen (som er grunnen til at Powershell tar over denne jobben for funksjoner og cmdlets). I tilfelle av cmd, vil jeg foreslå dette:

$param = "echo foo"
& cmd /c $param
Svarte 01/05/2009 kl. 02:02
kilden bruker

stemmer
9

Samtalen operatør '&' er unødvendig i dette tilfellet. Den brukes til å aktivere en kommando i en ny omfang. Dette blir vanligvis brukt til å aktivere en kommando som er angitt ved hjelp av en snor eller scriptblock. Det har også den fordel siden det noen variabler som er opprettet i si et Powershell script kastes etter at kommandoen er ferdig og omfang går unna.

Men siden cmd er en EXE det utfører i en helt annen prosess. FWIW, får du tilsvarende utgang direkte fra cmd.exe:

> cmd "/c echo foo"
foo"

Så ekstra sitat på slutten er en cmd.exe problem. Vanligvis må du holde kommandoen atskilt fra parametrene når Powershell gjør analyser å påkalle kommandoen f.eks

45> & { $foo = "foo" }
46> $foo  # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo 
foo

Den bemerkelsesverdig unntak her er at Invoke-Expression oppfører seg som en "evaluere denne strengen" -funksjon. Brukes med forsiktighet, spesielt hvis brukeren gir strengen. Dagen kunne suge hvis de leveres "ri C: \ r".

I dette tilfellet, som andre har antydet vil jeg trekke / c ut av strengen $ param streng og spesifisere det f.eks:

cmd /c $param

Eller bruke Invoke-Expression men bruk med forsiktighet. BTW når du prøver å feilsøke problemer med å sende argumenter til EXE fra Powershell, sjekk ut echoargs verktøyet i Powershell fellesskaps Extensions ( http://pscx.codeplex.com ). Det er veldig nyttig:

49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>

Dette viser at cmd.exe mottar "/ c ekko foo" som en enkelt argument. "/ c" må være et separat argument fra "echo foo" (kommandoen som skal utføres).

Svarte 01/05/2009 kl. 18:01
kilden bruker

stemmer
8

En annen måte jeg funnet for å gjøre dette var å skape en rekke argumenter for kommandolinjen og bruke den med apersand og ringe operatøren. Noe sånt som dette:

$exe = "cmd";
[Array]$params = "/c", "echo", "foo";

& $exe $params;

Det har fungert bra for meg.

Jeg opprinnelig funnet denne teknikken her: http://techstumbler.blogspot.com/2009/12/windows-commands-with-arguments-in.html

Svarte 09/12/2009 kl. 18:28
kilden bruker

stemmer
0

Args behandles annerledes når de finnes i en String:

PS D:\> echo "1 2 3"
1 2 3
PS D:\> echo 1 2 3
1
2
3

De samme resultatene oppstå når du bruker en variabel for args:

PS D:\> $param = "1 2 3"
PS D:\> echo $param
1 2 3

Løsningen er å bruke en Array:

PS D:\> $param = @(1,2,3)
PS D:\> echo $param
1
2
3
Svarte 20/12/2012 kl. 00:52
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more