GNU/Linux >> Znalost Linux >  >> Linux

Proč popen() vyvolá shell k provedení procesu?

Verze POSIX system() z roku 2004 dokumentace má zdůvodnění, které je pravděpodobně použitelné pro popen() také. Všimněte si uvedených omezení na system() , zejména ten, který uvádí „že ID procesu je jiné“:

ODŮVODNĚNÍ

...

Pro funkci system() existují tři úrovně specifikace. Norma ISO C poskytuje to nejzákladnější. Vyžaduje, aby funkce existovala, a definuje způsob, jakým se aplikace dotazuje, zda existuje interpret jazyka příkazů. Neříká nic o jazyce příkazu ani o prostředí, ve kterém je příkaz interpretován.

IEEE Std 1003.1-2001 klade na system() další omezení. Vyžaduje to, že pokud existuje interpret příkazového jazyka, prostředí musí být takové, jaké specifikují fork() a exec. To například zajišťuje, že close-on-exec funguje, že se zámky souborů nedědí a že ID procesu je odlišné. Určuje také návratovou hodnotu ze system(), kdy lze spustit příkazový řádek, čímž poskytuje aplikaci určité informace o stavu dokončení příkazu.

A konečně, IEEE Std 1003.1-2001 vyžaduje, aby byl příkaz interpretován jako příkazový jazyk shellu definovaný v Shell and Utilitiesvolume IEEE Std 1003.1-2001.

Všimněte si četných odkazů na "normu ISO C". Nejnovější verze standardu C vyžaduje, aby byl příkazový řetězec zpracován „příkazovým procesorem“ systému:

7.22.4.8 system funkce

Synopse

#include <stdlib.h>
int system(const char *string);

Popis

Pokud string je nulový ukazatel, system Funkce určuje, zda hostitelské prostředí má příkazový procesor. Pokud string není nulový ukazatel, system funkce předá řetězec, na který ukazuje string tomuto příkazovému procesoru, který má být proveden způsobem, který implementace dokumentuje; to může způsobit, že program volá system chovat se nekonformně nebo ukončit.

Vrátí se

Pokud je argumentem nulový ukazatel, system funkce vrací nenulovou hodnotu pouze v případě, že je k dispozici příkazový procesor. Pokud argument není nulový ukazatel, a system functiondoes return, vrátí implementačně definovanou hodnotu.

Protože standard C vyžaduje, aby byl pro system() použit systémový "příkazový procesor". zavolejte, mám podezření, že:

  1. Někde je v POSIX požadavek, který spojuje popen() na system() implementace.
  2. Je mnohem snazší znovu použít celý „příkazový procesor“, protože je zde také požadavek, aby běžel jako samostatný proces.

Takže toto je glib odpověď dvakrát odstraněna.


Vyvolání shellu vám umožní dělat všechny věci, které můžete dělat v shellu. Například

FILE *fp = popen("ls *", "r");

je možné pomocí popen() (rozbalí všechny soubory v aktuálním adresáři). Porovnejte s:

execvp("/bin/ls", (char *[]){"/bin/ls", "*", NULL});

Nemůžete spustit ls s * jako argument, protože exec(2) bude interpretovat * doslova.

Podobně potrubí (| ), přesměrování (> , < , ...), atd., jsou možné pomocí popen .

V opačném případě není důvod používat popen pokud shell nepotřebujete - je to zbytečné. Skončíte s procesem shellu navíc a všechny věci, které se mohou v shellu pokazit, se mohou pokazit ve vašem programu (např. příkaz, který předáte, může být shellem nesprávně interpretován a běžný bezpečnostní problém). popen() je navržena tak. fork + exec řešení je čistší bez problémů spojených s shellem.


Glib odpověď je proto, že to říká standard POSIX ( http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ). Nebo spíše říká, že by se měl chovat, jako kdyby byl argument příkazu předán do /bin/sh pro interpretaci.

Předpokládám tedy, že vyhovující implementace by v zásadě mohla mít také nějakou funkci vnitřní knihovny, která by interpretovala příkazy shellu, aniž by bylo nutné rozvětvovat a provádět samostatný proces shellu. Ve skutečnosti si nejsem vědom žádné takové implementace a mám podezření, že by bylo dost složité správně nastavit všechny rohové případy.


Linux
  1. Jak provést příkaz v prostředí Shell bez jeho uložení do historie? [Tipy pro Linux]

  2. Proč tento plášťový ropovod vystupuje?

  3. Co znamená &na konci linuxového příkazu?

  1. neselže sestavení jenkins, pokud selže spuštění shellu

  2. Co znamená syntaxe |&v jazyce shellu?

  3. Proč spouštět příkaz prostředí Linux s '&'?

  1. Proč substituce příkazů Shell pohltí znak na konci nového řádku?

  2. Proč můj systém Linux opakuje každý příkaz, který napíšu?

  3. Proč spuštění příkazu sudo trvá dlouho?