2010-06-21 18 views
11

Tengo un archivo ejecutable (ffmpeg) que estoy tratando de ejecutar con un programa Java en una Mac. He utilizado el programa Java para enviar el comando chmod 777 /path/to/ffmpeg, pero cuando trato de ejecutar ffmpeg, me sale el siguiente error:Error de permiso denegado en Java para el comando chmod

java.io.IOException: Cannot run program "/Users/james/WalkTheHall/ffmpeg": error=13, Permission denied 

Pero cuando corro chmod 777 /path/to/ffmpeg de la terminal por mi cuenta antes de abrir la aplicación Java, el comando ffmpeg funcionará bien en el programa Java.

¿Hay alguna diferencia entre llamar al chmod desde el programa Java y llamarlo por mi cuenta? ¿Por qué no va a funcionar? ¡Gracias!

+0

quizá está ejecutando el ejecutable java con un usuario que no tiene los privilegios a chmod ese archivo –

+0

detalles ... I don No lo sé en Mac, pero en GNU/Linux como usuario común no se puede hacer 'chmod 777' (algunos permisos están" enmascarados "), así que ¿es posible cuando intentas desde la terminal que eres de hecho el tipo de usuario que puede hacer? tal cosa, mientras ejecuta el Java como un usuario que no puede? (También es posible que java vm deje de tener privilegios cuando se ejecuta como usuarios "avanzados", solo para mejorar la seguridad) – ShinTakezou

Respuesta

4

Supongo que chmod es un comando de shell, no un ejecutable. Intenta ejecutar chmod a través de tu caparazón. Vea más detalles aquí: Want to invoke a linux shell command from Java

+0

Muchas gracias Carl, funcionó perfectamente para ejecutarlo con bash! –

+0

'which chmod' dice'/bin/chmod' para mí, así que bajo bash-3.2.48 es un ejecutable y no un shell incorporado. Tal vez lo que inicie Java no lo tenga en la ruta de búsqueda ejecutable, pero invocar el shell ejecuta los scripts de configuración del shell de los usuarios reparando PATH. –

4

Sí, hay una diferencia. Cuando ejecuta el comando desde la terminal, es usted quien realiza la acción y, por lo tanto, se realiza utilizando sus credenciales. La aplicación Java ejecuta el comando usando los permisos de la aplicación Java. Esto es para evitar que una aplicación se ejecute y luego realice cambios peligrosos y no deseados en el sistema de archivos. Quizás alguien más pueda elaborar y guiar una solución alternativa para esto.

+0

¡Gracias, Ryan! Seguramente hay una forma de ejecutar el programa dentro de Java. ¿Alguna idea sobre lo que debe hacer? –

+0

No estoy seguro. Parece que esto no debería permitirse por diseño, como dice el comentario de ShinTakezou sobre su pregunta, por razones de seguridad. ¿Has probado la respuesta de CarlG? Si funciona en Linux, definitivamente valdría la pena probarlo en Mac OS. –

2

Actualmente estoy trabajando en un proyecto que también hace uso de FFMpeg en OSX. Guardo FFMpeg en el JAR y lo extraigo y configuro el ejecutable en uso como parece que está haciendo. Esto es lo que hago, y parece funcionar.

 
public static void setExecutable(File file, boolean executable) 
{ 
    Process p = Runtime.getRuntime().exec(new String[] { 
     "chmod", 
     "u"+(executable?'+':'-')+"x", 
     file.getAbsolutePath(), 
    }); 
    // do stuff to make sure p finishes & capture output 
} 

El código es GPL, así que no dude en echarle un vistazo. No es la mejor base de código, e incluso el material de FFMpeg es quizás demasiado complejo, pero funciona.

Fuente es visible en http://korsakow.net

Estos dos archivos en particular podrían ser interesantes para usted

FFMpegEncoderOSX.java

FileUtil.java

+0

Gracias por la respuesta, ¡lo aprecio! Estoy ejecutando ese comando, pero todavía está dando un permiso de error denegado. ¿Alguna idea de por qué? –

5

acabo de tener el mismo problema en mi código. Lo resolví agregando waitFor after exec. El proceso "chmod" no termina cuando se ejecuta el siguiente comando. el código puede verse como:

p = Runtime.getRuntime.exec("chmod 777 xxx"); 
p.waitFor(); 
Runtime.getRuntime.exec("./xxx"); 
1

Prueba esto:

commandFile.setExecutable(true); 
Process p = Runtime.getRuntime.exec(commandFile.getAbsoluteFile());