Distribución de un script: ¿Debo usar / bin / gawk o / usr / bin / gawk para shebang?


12

¿Gawk está en / bin o / usr / bin por lo general? Iría con #!/usr/bin/env gawkpero no puedo usar argumentos. Ahora mismo lo estoy usando #!/bin/gawk -f. El script es muy largo y contiene muchas comillas simples y funciona con stdin.

El manual de GNU Awk tiene la sección 1.1.4 Programas ejecutables awk donde usa #! / Bin / awk en su ejemplo pero continúa diciendo:

Tenga en cuenta que en muchos sistemas awkse pueden encontrar en /usr/binlugar de en /bin. Advertencia Emptor.

¿Qué hace la mayoría de la gente? Leí que sed supuestamente está estandarizado en / bin, mientras que perl supuestamente está estandarizado en / usr / bin (la misma página que sed link pero no me dejan hacer un tercer enlace para esta publicación). ¿Qué pasa con awk / gawk? ¿Alguien sabe cuál es más común o popular?


¿Por qué lo usas -f? ¿No es /bin/gawksuficiente? Además, esto podría ser relevante.
terdon

Respuestas:


7

Shebang no estaba destinado a ser tan flexible . Puede haber algunos casos en los que funciona tener un segundo parámetro , creo que FreeBSD es uno de ellos.

Se espera que gawk y la mayoría de las utilidades que vienen con el sistema operativo estén incluidas /usr/bin/.

En los viejos tiempos de UNIX, era común haberse /usr/montado sobre NFS o algunos medios menos costosos para ahorrar espacio en disco local y costo por estación de trabajo. /bin/se suponía que tenía todo lo necesario para arrancar en modo de usuario único . Como /usr/no se montó en un medio confiable, /bin/incluyó suficientes utilidades para que sea lo suficientemente amigable para la administración general y la solución de problemas.

Inicialmente, esto se heredó en Linux, pero como el espacio en disco ya no es un problema y, en la mayoría de los casos, /usr/está en el sistema de archivos raíz, la tendencia actual es mover todo /usr/bin(al menos en el mundo de Linux). Por lo tanto, se espera que la mayoría de las utilidades instaladas por una distribución se encuentren allí. Incluso la mayoría de las empresas de servicios públicos básicos, como cp, rm, lsetc (bueno, no todavía).

En cuanto a la elección shebang. Tradicionalmente, esto es algo que los administradores o usuarios tienen que editar de acuerdo con su entorno. Por lo que un desarrollador sabe, en los sistemas de otras personas, el intérprete podría estar en cualquier parte del sistema de archivos (por ejemplo /usr/local/bin, /opt/gawk-4.0.1/bin). Los scripts correctamente empaquetados (rpm, deb, etc.) vienen con una dependencia de un paquete de distribución (es decir, el intérprete tiene una ubicación conocida) o un script de configuración que configura el hashbang adecuado durante la instalación.


14

Si no necesita pasar argumentos al comando, entonces este #!/usr/bin/env gawkes el camino a seguir, sin embargo, muchos núcleos (incluido Linux) solo aceptan un único argumento para los programas shebang.

De lo contrario, puede crear un programa políglota que sea tanto un envoltorio de shell como el script awk. Aquí hay uno para awk.

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

Análisis de shell:

  • true + /;- el comando true(que no hace nada) con dos argumentos inertes +y /.
  • La llamada a gawk. Esto podría ser cualquier fragmento de shell que no contenga nuevas líneas y donde se escriban barras inclinadas \/(al shell no le importa, excepto entre comillas).
    La llamada utiliza execpara reemplazar el shell con gawk en lugar de ejecutar gawk como un subproceso.
  • exit;- Salga del shell, en caso de que no se encuentre gawk. Cualquier cosa después de eso se ignora, excepto que debería ser una sintaxis de shell válida en caso de que el shell intente analizar toda la línea antes de comenzar a ejecutarla.

Awk análisis:

  • El bit entre barras es una expresión regular.
  • true + /REGEX/- Una condición. truees una variable indefinida, por lo que su valor numérico es 0, no es que importe.
  • {} - Si dicha condición se cumple, no haga nada.

5

La solución propuesta de Gilles es de hecho un muy buen enfoque (finalmente tiene la reputación de votar en su publicación :)).

En cualquier caso, hasta donde entiendo el execcomando, hace que el exitderecho después de que sea innecesario, realmente inalcanzable, ya que el proceso de shell se reemplaza por awk.

Además, para permitir que el awkscript acceda a sus parámetros de invocación, sugeriría algunos cambios en la solución propuesta:

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

El -a "$0"permite que la secuencia de comandos para tener acceso a su nombre de invocación, de lo contrario, siempre se obtendrá una awko gawkcuando se accede a la ARGV[0]variable. Del mismo modo, "$@"permite que el script acceda a los parámetros restantes en la ARGV[1...N]matriz y lo --anterior permite que el script reciba -<something>argumentos sin que gawk los interprete.

Una cosa para recordar / considerar es agregar una exit(0);declaración al final del BEGIN { ... }bloque del awkprograma de script, de lo contrario awkamenazará todos los parámetros pasados ​​al script como archivos de entrada. (Tenga en cuenta que no tiene nada que ver, en absoluto, con la exitdeclaración que eliminamos de la true + ...línea, esta fue una declaración de shell inalcanzable, mientras que esta salida sugerida está en el código awk).


El exit(0)fue muy útil! Además, para usuarios de macos, vean esta idea: un buen awk shebang portátil no es fácil de encontrar.
Seamus
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.