Bør jeg flykte shell argumenter i Perl?

stemmer
14

Ved bruk av system () kaller i Perl, har du å flykte skallet args, eller er det gjort automatisk?

Argumentene vil være brukerundersøkelser, så jeg ønsker å sørge for at dette ikke utnyttes.

Publisert på 06/03/2009 klokken 18:33
kilden bruker
På andre språk...                            


5 svar

stemmer
37

Hvis du bruker system $cmd, @argsi stedet for system "$cmd @args"(en matrise i stedet for en streng), så du trenger ikke å unnslippe argumentene fordi ingen skallet er påberopt (se system ). system {$cmd} $cmd, @argsvil ikke påkalle en skall enten selv om $ cmd inneholder metategn og @args er tom (dette er dokumentert som en del av exec ). Hvis args kommer fra brukerundersøkelser (eller annen upålitelig kilde), vil du fortsatt ønsker å untaint dem. Se -Tperlrun docs, og perlsec docs.

Hvis du trenger å lese utgang eller sende innspill til kommandoen, qxog readpipehar ikke noe tilsvarende. I stedet bruker open my $output, "-|", $cmd, @argseller open my $input, "|-", $cmd, @argsselv om dette ikke er bærbar som det krever en reell forksom betyr Unix bare ... tror jeg. Kanskje det vil fungere på Windows med simulert gaffel. Et bedre alternativ er noe som IPC :: Run , som også vil håndtere saken av rør kommandoer til andre kommandoer, som verken multi-arg form for system eller 4 arg form for åpen vil håndtere.

Svarte 06/03/2009 kl. 18:43
kilden bruker

stemmer
13

På Windows, er situasjonen en litt slemmere. I utgangspunktet alle Win32 programmer får en lang kommando-linje streng - skallet (vanligvis cmd.exe) kan gjøre noen tolkning første, fjerne <og >redirections for eksempel, men det trenger ikke dele den opp på ordet grenser for programmet. Hvert program må gjøre dette parsing seg selv (hvis de ønsker det - noen programmer ikke bry). I C og C ++ programmer, vil rutiner gitt av kjøretidsbiblioteker som følger med kompilatoren-verktøyene generelt utføre denne parsing trinnet før main()kalles.

Problemet er, generelt, trenger du ikke vet hvordan et gitt program vil analysere sin kommandolinjen . Mange programmer er kompilert med en versjon av MSVC ++, hvis quirky parsing Reglene er beskrevet her , men mange andre er kompilert med ulike kompilatorer som bruker ulike konvensjoner.

Dette er forsterket av det faktum at cmd.exehar sine egne sære parsing regler. Cirkumflekstegnet ( ^) behandles som en flukt karakter som siterer følgende karakter, og teksten i anførselstegn behandles som sitert om en liste over vanskelige kriterier er oppfylt (se cmd /?for full blodig detaljer). Hvis din kommando inneholder noen rare tegn, er det veldig lett for cmd.exesin idé om hvilke deler av teksten er 'sitert' og som ikke er til å komme ut av sync med målet for programmet, og helvete bryter løs.

Så, den sikreste metode for å unnslippe argumenter på Windows er:

  1. Escape argumenter på den måten som forventes av kommandolinjen parsing logikken i programmet du ringer. (Forhåpentligvis vet du hva den logikken er, hvis ikke, kan du prøve noen eksempler og gjetning.)
  2. Bli den rømte argumenter med mellomrom.
  3. Prefiks hver eneste ikke-alfanumerisk tegn av den resulterende strengen med ^.
  4. Føye til videresending eller annet skall list (f.eks sammenføyning kommandoer med &&).
  5. Kjør kommandoen med system()eller backticks.
Svarte 08/03/2009 kl. 07:11
kilden bruker

stemmer
0

Svarene på spørsmålet ditt var svært nyttig. Til slutt fulgte jeg @ Runrig råd, men da anvendes kjernemodulen open3 () -kommando slik at jeg kan fange opp utgangssignalet fra STDERR samt STDOUT.

For eksempelkode for open3 () i bruk med @ Runrig løsning, se min relaterte spørsmål og svar:
Calling system kommandoer fra Perl

Svarte 13/12/2010 kl. 17:11
kilden bruker

stemmer
2
 sub esc_chars {
  # will change, for example, a!!a to a\!\!a
     @_ =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
     return @_;
  }

http://www.slac.stanford.edu/slac/www/resource/how-to-use/cgi-rexx/cgi-esc.html

Svarte 19/11/2011 kl. 02:53
kilden bruker

stemmer
1

Hvis du bruker system "$ cmd @args" (en streng), så må du unnslippe argumentene fordi en skallet er påberopt.

Heldigvis for dobbel sitert strenger, bare fire tegn må rømme:

"    - double quote
$    - dollar
@    - at symbol
\    - backslash
Svarte 03/11/2013 kl. 12:02
kilden bruker

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