Distribution d'un script: dois-je utiliser / bin / gawk ou / usr / bin / gawk pour shebang?


12

Est-ce que gawk se trouve généralement dans / bin ou / usr / bin? J'irais avec #!/usr/bin/env gawkmais je ne peux pas utiliser d'arguments. En ce moment j'utilise #!/bin/gawk -f. Le script est très long et contient beaucoup de guillemets simples et fonctionne avec stdin.

Le manuel GNU Awk contient la section 1.1.4 Programmes exécutables awk où il utilise #! / Bin / awk dans son exemple mais continue en disant:

Notez que sur de nombreux systèmes awkse trouvent dans /usr/binau lieu de dans /bin. Caveat Emptor.

Que font la plupart des gens? J'ai lu que sed est censé être standardisé dans / bin tandis que perl est censé être standardisé dans / usr / bin (même page que le lien sed mais ils ne me laisseront pas faire un troisième lien pour ce post). Et awk / gawk? Est-ce que quelqu'un sait ce qui est le plus courant ou le plus populaire?


Pourquoi utilisez-vous -f? Ça ne /bin/gawksuffit pas ? En outre, cela pourrait être pertinent.
terdon

Réponses:


7

Shebang n'était pas censé être aussi flexible . Il peut y avoir des cas où avoir un deuxième paramètre fonctionne , je pense que FreeBSD en fait partie.

gawk et la plupart des utilitaires fournis avec le système d'exploitation devraient être disponibles /usr/bin/.

Dans les anciens jours UNIX, il était courant d'avoir /usr/monté sur NFS ou sur un support moins cher pour économiser de l'espace disque local et le coût par poste de travail. /bin/était censé avoir tout le nécessaire pour démarrer en mode mono-utilisateur . Comme il /usr/n'était pas monté sur un support fiable, il /bin/comprenait suffisamment d'utilitaires pour le rendre suffisamment convivial pour l'administration générale et le dépannage.

Cela a été hérité sous Linux au départ, mais comme l'espace disque n'est plus un problème et dans la plupart des cas /usr/dans le système de fichiers racine, la tendance actuelle est de tout déplacer /usr/bin(au moins dans le monde Linux). La plupart des utilitaires installés par une distribution devraient donc s'y trouver. Même les plus les services de base, comme cp, rm, lsetc (bien, pas encore).

Concernant le choix du shebang. Traditionnellement, c'est quelque chose que les administrateurs ou les utilisateurs doivent modifier en fonction de leur environnement. Pour tout ce qu'un développeur sait, dans les systèmes d'autres personnes, l'interpréteur peut se trouver n'importe où dans le système de fichiers (par exemple /usr/local/bin, /opt/gawk-4.0.1/bin). Les scripts correctement emballés (rpm, deb, etc.) sont livrés soit avec une dépendance à un package de distribution (c'est-à-dire que l'interpréteur a un emplacement connu) soit avec un script de configuration qui configure le hashbang approprié lors de l'installation.


14

Si vous n'avez pas besoin de passer d'arguments à la commande, #!/usr/bin/env gawkc'est le chemin à parcourir, cependant de nombreux noyaux (y compris Linux) n'acceptent qu'un seul argument pour les programmes shebang.

Sinon, vous pouvez créer un programme polyglotte qui est à la fois un wrapper shell et le script awk. En voici un pour awk.

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

Analyse du shell:

  • true + /;- la commande true(qui ne fait rien) avec deux arguments inertes +et /.
  • L'appel à gawk. Il peut s'agir de n'importe quel extrait de shell qui ne contient pas de nouvelles lignes et où des barres obliques sont écrites \/(le shell ne dérange pas, sauf entre guillemets).
    L'appel utilise execpour remplacer le shell par gawk au lieu d'exécuter gawk en tant que sous-processus.
  • exit;- quitter le shell, au cas où gawk n'a pas été trouvé. Tout ce qui suit est ignoré, sauf qu'il doit s'agir d'une syntaxe de shell valide au cas où le shell tente d'analyser la ligne entière avant de commencer à l'exécuter.

Analyse awk:

  • Le bit entre les barres obliques est une expression régulière.
  • true + /REGEX/- une condition. trueest une variable indéfinie, sa valeur numérique est donc 0, ce n'est pas important.
  • {} - Si cette condition se vérifie, ne faites rien.

5

La solution proposée par Gilles est en effet une très bonne approche (enfin avoir la réputation de voter dans son poste :)).

Dans tous les cas, pour autant que je comprends la execcommande, elle rend le exitdroit après inutile, en fait inaccessible, car le processus shell est remplacé par awk.

De plus, afin de permettre au awkscript d'accéder à ses paramètres d'invocation, je suggérerais quelques changements dans la solution proposée:

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

Le -a "$0"permet au script d'avoir accès à son nom d'invocation, sinon il obtiendra toujours un awkou gawklors de l'accès à la ARGV[0]variable. De même, le "$@"permet au script d'accéder aux paramètres restants du ARGV[1...N]tableau et le --précédent permet au script de recevoir des -<something>arguments sans que gawk les interprète lui est destiné.

Une chose à retenir / à considérer est d'ajouter une exit(0);instruction à la fin du BEGIN { ... }bloc du awkprogramme de script, sinon awkcela menacera tous les paramètres passés au script en tant que fichiers d'entrée. (Veuillez noter que cela n'a rien à voir du tout avec l' exitinstruction que nous avons supprimée de la true + ...ligne, c'était une instruction shell inaccessible alors que cette sortie suggérée est dans le code awk).


Le exit(0)était très utile! De plus, pour les utilisateurs de macos, voyez cet essentiel: un bon shekang portable awk n'est pas facile à trouver.
Seamus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.