2010-02-22 10 views
6

¿Por qué prefiere evitar el uso de comandos bash a través de exec() en php?¿Por qué no debería usar comandos de Unix de php?

No considero el problema de la portabilidad (definitivamente no lo portaré para ejecutarlo en Windows). Esa es solo una cuestión de una buena forma de escribir guiones.

Por un lado:

  1. tengo que escribir mucho más líneas en php a continuación, en bash para llevar a cabo la misma tarea. Por ejemplo, cuando necesito filtrar algunas líneas en un archivo, simplemente no puedo crear imágenes usando algo en lugar de cat file | grep string > new_file. Esto tomaría mucho más tiempo y esfuerzo para hacer en php.
  2. No quiero analizar todas las situaciones cuando algo puede salir mal. Simplemente mostraré el resultado del comando bash al usuario, para que él supiera exactamente qué sucedió.
  3. No necesito escribir otro contenedor sobre las funciones del sistema de archivos y usarlo. Es mucho más eficiente para aprovechar el sistema operativo para la búsqueda de archivos, manipulación, etc.

Por otro lado:

  1. Llamada de comandos UNIX con exec() podría ser ineficaz en la mayoría de los casos. Es bastante costoso generar un proceso separado. No se trata de secuencias de comandos que se ejecutan en Apache, que es incluso mucho menos eficiente que la creación de scripts de línea de comandos.
  2. A veces resulta ser 'magia negra' y secuencias de comandos perl. Aunque se puede evitar a través de comentarios detallados.
  3. Tal vez estoy tratando de usar dos herramientas diferentes juntas cuando se supone que no deben hacerlo. Cada herramienta tiene su propia aplicación y no debe mezclarse.
  4. Aunque estoy seguro de que los usuarios no intentarán ejecutar secuencias de comandos con propósitos maliciosos, usar exec() es una posible amenaza a la seguridad. En la mayoría de los casos, los datos del usuario se pueden escapar con escapeshellarg(), pero aún así es un problema a tener en cuenta.
+0

Si llama a scripts bash para filtrar algunas líneas en un archivo, entonces lo está haciendo mal. Creo que su número 2 y 3 enumerados en "por otro lado" son exactamente la razón por la que no hace esto. – GreenieMeanie

Respuesta

10

¿Qué estás tratando de lograr? PHP tiene funciones basadas en expresiones regulares para encontrar lo que necesita de un archivo. Sí, probablemente necesitarías alrededor de 5 líneas de código para hacerlo, pero probablemente no sería más o menos eficiente.

La razón principal contra el uso de exec() en PHP es por seguridad. Si confías en que tu usuario te dará un comando para ejecutar exec() en bash, podría ejecutar fácilmente comandos maliciosos, como instalar e iniciar troyanos de puerta trasera, eliminar archivos y cosas similares.

Sin embargo, siempre que tenga cuidado (use los comandos de escape de shell para limpiar la entrada del usuario, restrinja los permisos de usuario de Apache, etc.) no debería ser un problema. En este momento estoy trabajando en una plataforma completa, que depende de los procesos de shell que ejecutan front-end simplemente porque C++ es mucho más rápido que PHP, así que escribí mucha lógica de back-end como una aplicación de shell y mantuve PHP para la lógica del front-end.

1

Personalmente, si la portabilidad no es un problema, utilizaría totalmente los comandos * nix como grep, locate, etc., cualquier día sobre tratar de duplicar esa funcionalidad en PHP.

Se trata de utilizar la mejor herramienta para el trabajo. En algunos casos, podría decirse que con más frecuencia de lo que la mayoría de la gente piensa, es mucho más eficiente aprovechar el sistema operativo para búsquedas de archivos, manipulación, etc. (entre otras cosas)

1

Mucha gente descendería sobre usted como una tonelada de ladrillos por incluso mencionar el uso de exec. Algunas personas considerarían que es una blasfemia, pero yo no. No puedo ver nada mal con el ejecutivo en algunas situaciones si su servidor se ha configurado correctamente. La desventaja es que está generando otro proceso.

+0

El desove es bastante caro. Es (casi) siempre * mucho * menos eficiente que usar PHP. – Jacco

+0

Acepto que engendrar otro proceso es costoso. – e4c5

14

Otra razón para evitar esto es que es mucho más fácil crear agujeros de seguridad como este. por ejemplo, si un usuario se las arreglan para colarse

`rm -rf /` 

(Con acentos abiertos) en la entrada, su código de fiesta en realidad podría bombardear el servidor (o nuclear algo por lo menos).

esto es sobre todo una cuestión religiosa, la mayoría de los desarrolladores intentan escribir código que siempre funciona.confiar en los comandos externos es una forma segura de hacer que su código falle en algunos sistemas (incluso en el mismo sistema operativo).

+0

Estoy de acuerdo con su último párrafo, pero tengo dificultades para ver el agujero de seguridad en el primero, ¿no se aplica solo cuando el código se ejecuta con eval()? –

+2

intente este:

+0

Ahh, eso es lo que quieres decir. Bueno, pero para eso sirve 'escapeshellarg()', ¿no es así? ¿O eso no es atrapado? –

3

En mi humilde opinión, la principal preocupación con el uso de exec() para ejecutar comandos * nix a través de PHP es la seguridad, más que el rendimiento o incluso el estilo del código.

Si tiene muy buena desinfección de la entrada (y esto es muy difícil de lograr), es posible que no pueda tener ningún agujero de seguridad.

1

Si está ejecutando su PHP utilizando un servidor web, es posible que el "usuario" que ejecuta el script no tenga permiso para ejecutar ciertos comandos de shell. usted dijo que la portabilidad no es un problema, pero puedo garantizarle que ES un problema (a menos que esté creando scripts PHP por diversión). En el mundo de los negocios, donde las cosas y las condiciones cambian rápidamente, no sabrá que algún día tendrá que ejecutar sus scripts en otras plataformas.

0

Si la portabilidad realmente no es un problema, porque está construyendo una solución de empresa que siempre estará en sus propios servidores, totalmente controlados, digo que busque comandos de shell tanto como desee. No existe un problema de seguridad inherente siempre que realice un saneamiento básico adecuado usando escapeshellarg() y consortes.

Al mismo tiempo, en mis proyectos la portabilidad es sobre todo un problema, y ​​cuando lo es, trato de no usar comandos de shell en absoluto, solo cuando algo no se puede hacer en PHP (por ejemplo, decodificación de MP3/codificación, ImageMagick, operaciones de video) o no es razonable (es decir, una solución basada en PHP es demasiado lenta) ¿Usaré comandos externos?

4

Aunque diga que la portabilidad no es un problema, nunca se sabe con certeza lo que depara el futuro, por lo que le recomiendo que reconsidere esa posición. Por ejemplo, una vez me pidieron que transfiriera un editor que fue escrito (por alguien más) de Unix a DOS. No se esperaba que el programa original fuera portado y fue escrito con llamadas específicas de Unix profundamente integradas en el código. Después de revisar la cantidad de trabajo requerido, abandonamos la tarea por demasiado tiempo.

He utilizado las llamadas de ejecución en PHP; sin embargo, no tenía otra manera de lograr lo que necesitaba (tuve que llamar a otro programa escrito en otro idioma sin otro puente entre los idiomas). Sin embargo, IMO, las llamadas del ejecutivo que no son necesarias son feas. Como otros han dicho, también pueden crear riesgos de seguridad y desacelerar su programa.

Como dijo usted mismo, debe documentar bien las llamadas de la ejecutiva para asegurarse de que los programadores las entiendan. ¿Por qué crear el trabajo extra? No solo ahora sino en el futuro, cuando cualquier cambio en la llamada del ejecutivo también deba documentarse.

Finalmente, sugiero que aprenda PHP y sus funciones un poco mejor.No soy tan bueno con PHP, pero en sólo cuestión de minutos con Google y php.net, creo que he logrado lo mismo que usted ha puesto como ejemplo con:

$search_results = preg_grep($search_string, file($file_name)); 
foreach ($search_results as $result) { 
    echo $result . "\n"; 
} 

Sí, es un poco más código, pero no tanto, y puedes ponerlo en una función si es apropiado ... y no me sorprendería si un gurú de PHP pudiera acortarlo.

+0

Realmente no creo que deba portar el script a DOS :) Pero aún así, ¿qué incompatibilidades entre el sistema operativo basado en UNIX enfrentaste? ¿Tienes algunos ejemplos que aparecen en tu mente? – altern

+0

@altern: esto fue hace unos 20 años, gran parte de esto ahora es un recuerdo débil (y doloroso) ... De todos modos, la versión de Unix fue escrita usando maldiciones, y aún no había un puerto de maldiciones para DOS (o al menos no sabíamos de uno). Por lo tanto, todas las cosas de la pantalla, que no estaban separadas del código de procesamiento, tendrían que haber cambiado un elemento a la vez, ya que cada elemento era bastante único. No recuerdo cuántas llamadas curses encontramos, pero fueron varios cientos, o tal vez incluso algunos miles. – GreenMatt

1

php no es un buen ejecutor. php genera un proceso desde apache, y si ese proceso se bloquea, tu servidor apache se bloqueará, si tu sitio también se ejecuta en el mismo apache; fallará

También puede tener problemas tan tontos como estos, si esto sucede, no puede incluso reiniciar apache sin matar manualmente el proceso generado del shell.

http://bugs.php.net/bug.php?id=38915

, por lo tanto, no estoy hablando de la seguridad, la ejecución de comandos de Linux desde PHP no más de lo que parece, la peor parte de la utilización ejecutivo, que no siempre es posible conseguir los mensajes de error de nuevo a php. o escriba el método subsiguiente que depende de lo que sucedió con el ejecutivo.

consideran que este seudo ejemplo:

exec ('bash myscript.sh',$x) 
if (myScriptWasOk == true) then do this 

No hay manera de que usted consigue esa variable derecha 'myScriptWasOk'. Simplemente no sabes nada al respecto, $ x te ayudará a veces.

Dicho todo esto, si necesitas algo simple, y si has probado tu script y funciona bien, solo hazlo.

+0

Tengo script de línea de comandos. Apache no tiene nada que ver con esto, afortunadamente. Ciertamente no consideraría (o pensaría 10 veces antes) el uso de exec en scripts web. – altern

+0

no he probado php-cli, así que no puedo decir mucho. – Devrim

1

No es seguro a menos que tome precauciones extremas para asegurarse de que no pueda ser utilizado por las personas que ejecutan el código.

1

Si solo está buscando la compatibilidad con Unix (lo cual está perfectamente bien), no veo nada de malo en ello. Prácticamente el sistema operativo de servidor disponible en la actualidad es un clon de Unix, excepto, por supuesto, para Windows, que creo que es ridículo usar como plataforma de servidor en primer lugar (y estoy hablando por experiencia aquí, esto no es solo odio de Microsoft). La compatibilidad Unix es un requisito perfectamente legítimo en cualquier servidor en mi opinión.

La única razón real que puedo ver para evitarlo es el rendimiento. Descubrirá rápidamente que la ejecución de procesos externos en general es extremadamente lenta. Es lento en C, y es lento en PHP. Creo que esa es la mayor preocupación real, no religiosa.

EDIT: Ah, y en cuanto al problema de seguridad, esa es una simple cuestión de asegurarse de que tiene el control total de las variables pasadas al sistema operativo. Es una preocupación que tiene que hacer cuando se comunica entre procesos e idiomas de todos modos, por ejemplo, cuando hace consultas SQL. No es una razón lo suficientemente grande en mi opinión para no hacer algo, es algo que debe tenerse en cuenta en este caso, como en todos los casos.

Cuestiones relacionadas