Estoy buscando en una forma más eficiente para decidir:Java, Runtime.exec o ProcessBuilder: cómo saber si el archivo es shell o binario?
- ¿Debo antepóngale la línea de comandos proporcionada por el usuario con el ejecutable de shell
- En caso afirmativo, ¿cuál sería ese ejecutable? (/ bin/sh?/usr/bin/perl?/usr/bin/ksh? c: /../ cmd.exe?)
Se sabe que para iniciar un script de shell desde Java se debe se inicia la cáscara en su lugar:
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2);
Para iniciar un uno binario debe comenzar el binario en sí:
ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2);
Si un binario se ejecuta con la cáscara, se produce un error:
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2);
(sh: cannot execute binary file)
Si un script se ejecuta sin la cáscara binaria, se produce un error:
ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2);
(error 2: file not found)
Estoy en una situación en la que mi aplicación no sabe lo que se inicia, binario o un script.
La aplicación iniciada es un controlador de eventos proporcionado por el usuario final. Lo más probable es que sea un script de shell ejecutado bajo Unix; pero puede ser * .cmd en Windows, o un script Perl ejecutado bajo alguna plataforma oscura. Es Java, después de todo.
Mi primer intento ingenuo fue iniciar la línea de comandos con el shell, y ver si funciona. Si no, intente ejecutarlo como un binario.
Esto es feo y arriesgado: bajo una combinación desconocida de plataforma y shell el segundo ejecutado aún puede ejecutar el script, por segunda vez, con resultados impredecibles.
Además, no puedo decir cuándo la secuencia de comandos comenzó bien y falló debido a algún problema de cuando simplemente no puedo iniciarlo.
Lo mejor que estoy considerando ahora es:
- leyó el guión y buscar los bytes no imprimible
- Si lo encuentra, lo consideran un binario
- Si no es así, añadir/bin/sh (o cmd.exe si está en Windows)
Indique si tiene alguna idea mejor en mente.
ACTUALIZACIÓN/solución parcial
Gracias a todos los que compartieron sus pensamientos conmigo.
Resulta que he confundido mí y para el resto de la Internet :)
No es necesario estar precedidos por se binarios antes de la línea de comandos introducidos por el usuario siempre que:
- el guión está en PATH
- (para Unix) el guión es ejecutable
- (para Unix) tiene la secuencia de comandos #!/ruta/a/intérprete
Mientras estaba probando mi código, una u otra de estas condiciones no cumplió. :-(
Después de realizar la prueba cuidadosamente el guión cero ha sido ejecutado.
El punto 3 se sólo se puede hacer por el usuario, y tienen que ser documentado en el Manual del usuario.
Debido a la forma en que estos scripts se propagan al sistema de destino, pueden no ser ejecutables y pueden no estar en PATH.
El único camino que me importa es uno relativo, por lo que es suficiente anteponer un ./ a cualquier ruta relativa
Making th Los scripts ejecutables bajo Unix (y cualquier otra plataforma) son un desafío mayor. No es WORA. Colocar/bin/sh delante de él puede ayudar, pero si recuerdo bien en Solaris, el shell no ejecutará un script no ejecutable.
Voy a publicar otra actualización más adelante esta semana.
¿Su script de shell tiene una línea shebang apropiada ('#!') En la parte superior? Si es así, simplemente puede pedirle al núcleo que lo ejecute (siempre que sea el ejecutable '+ x') sin preocuparse por qué intérprete de comandos pueda necesitar. –
No puedo saberlo. La secuencia de comandos proviene de usuarios finales que no se suministran con el software. –