Tengo un script de python, que quiero poder ejecutar desde bash.
Esto simplemente se resuelve con shebang.
El siguiente paso es implementar el comando de tiempo en el shebang.
Mi mejor idea, pero no la más exitosa, fue usar

#!/usr/bin/env -vS bash -c "time /usr/bin/python3 -OO"

Lo que lamentablemente no hace que Python interprete el archivo de script y termina en una sesión interactiva de Python.

La salida es

split -S:  ‘bash -c "time /usr/bin/python3 -OO"’
 into:    ‘bash’
     &    ‘-c’
     &    ‘time /usr/bin/python3 -OO’
executing: bash
   arg[0]= ‘bash’
   arg[1]= ‘-c’
   arg[2]= ‘time /usr/bin/python3 -OO’
   arg[3]= ‘./mypycheck.py’
Python 3.7.3 (default, Apr  3 2019, 05:39:12)

¿Cómo puedo hacer el trabajo? Gracias por adelantado.

2
Bastian Ebeling 28 sep. 2019 a las 11:21

4 respuestas

La mejor respuesta

Al final, resumiendo todos los detalles útiles de aquí, pude alcanzar mi objetivo con la siguiente solución.

  1. Instalación de la utilidad time ejecutando sudo apt install time
  2. Usando el shebang #!/usr/bin/env -S /usr/bin/time /usr/bin/python3 -OO

Y ahora todo funciona como estaba buscando.

1
Bastian Ebeling 29 sep. 2019 a las 12:45

Supongo que ya lo intentaste

#!/usr/bin/time python3

¿No estuvo bien? (es decir, ¿es obligatorio el -OO en sus pruebas?)

Ejemplo:

$ cat test.py
#!/usr/bin/time python3
import sys
print (sys.argv)

$ ./test.py 
['./test.py']
0.01user 0.00system 0:00.02elapsed 95%CPU (0avgtext+0avgdata 9560maxresident)k
0inputs+0outputs (0major+1164minor)pagefaults 0swaps

Aunque esto aún no resuelve el -OO

1
Demi-Lune 28 sep. 2019 a las 09:14

No puede hacerlo con un shebang, porque su formato (en Linux) es:

#!interpreter [optional-arg]

Y este argumento se pasa como una sola cadena (consulte "Scripts de intérprete" y "Scripts de intérprete" en el documento vinculado). En otras palabras, no puede pasar múltiples argumentos (a menos que se puedan concatenar a una sola cadena) a un intérprete. Esto se debe a la implementación del núcleo de cómo se ejecuta el código.

El uso de env -S tampoco es útil aquí, porque como puede ver en su salida de depuración:

   arg[0]= ‘bash’
   arg[1]= ‘-c’
   arg[2]= ‘time /usr/bin/python3 -OO’
   arg[3]= ‘./mypycheck.py’

Ejecuta shell, le dice que ejecute un comando (-c) iniciando python envuelto en time y luego pasa ‘./mypycheck.py’ a bash (no python) como último argumento. significado de lo cual es (aplicable a la fiesta):

-c

Si la opción -c está presente, los comandos se leen desde el primer argumento sin opción command_string. Si hay argumentos después de command_string, el primer argumento se asigna a $0 y los argumentos restantes se asignan a los parámetros posicionales. La asignación a $0 establece el nombre del shell, que se utiliza en advertencia y mensajes de error.

En cuanto a tu objetivo. Puede crear un contenedor que se utilice como intérprete en lugar de env en su caso que realice las acciones deseadas y pase el guión a un intérprete real.

1
Ondrej K. 28 sep. 2019 a las 09:02

Puede resolver esto creando un script bash secundario e invocandolo como shebang.

Kamori@Kamori-PC:/tmp# ./timed.py
hello

real    0m0.028s
user    0m0.016s
sys     0m0.000s
Kamori@Kamori-PC:/tmp# cat timed.py
#!/bin/bash startup.sh

print("hello")
Kamori@Kamori-PC:/tmp# cat startup.sh
#!/usr/bin/env bash

time python3.7 timed.py
1
Kamori 28 sep. 2019 a las 08:42
58144588