Je voudrais exécuter un script gawk en --re-interval
utilisant un shebang. L'approche «naïve» de
#!/usr/bin/gawk --re-interval -f
... awk script goes here
ne fonctionne pas, car gawk est appelé avec le premier argument "--re-interval -f"
(non divisé autour de l'espace blanc), qu'il ne comprend pas. Y a-t-il une solution de contournement pour cela?
Bien sûr, vous pouvez soit ne pas appeler directement gawk mais l'envelopper dans un script shell qui divise le premier argument, soit créer un script shell qui appelle ensuite gawk et place le script dans un autre fichier, mais je me demandais s'il y avait un moyen de faire ceci dans un fichier.
Le comportement des lignes shebang diffère d'un système à l'autre - du moins dans Cygwin, il ne divise pas les arguments par des espaces. Je me soucie juste de savoir comment le faire sur un système qui se comporte comme ça; le script n'est pas destiné à être portable.
--re-interval
n'est plus nécessaire (voir [ gnu.org/software/gawk/manual/… ).Réponses:
Cela semble fonctionner pour moi avec (g) awk.
Notez les
#!
exécutions/bin/sh
, donc ce script est d'abord interprété comme un script shell.Au début, j'ai simplement essayé
"exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"
, mais awk a traité cela comme une commande et imprimé chaque ligne d'entrée sans condition. C'est pourquoi j'ai mis learbitrary_long_name==0
- il est censé échouer tout le temps. Vous pouvez le remplacer par une chaîne de charabia. En gros, je cherchais une fausse condition dans awk qui n'affecterait pas négativement le script shell.Dans le script shell, le
arbitrary_long_name==0
définit une variable appeléearbitrary_long_name
et la définit égale à=0
.la source
bash
, ou fonctionnera-t-il avec n'importe quel POSIXsh
? Et je n'utilise pasawk
souvent, donc je ne suis pas sûr que mon truc sur la deuxième ligne soit un bon moyen de forcerawk
à ignorer la ligne.arbitrary_long_name
n'entre pas en conflit avec une variable utilisée dans le vrai programme awk, je ne vois aucun problème. Y a-t-il quelque chose qui me manque?#!/bin/sh -
place de#!/bin/sh
pour empêcher le script de se comporter de manière dangereuse s'il est invoqué avec un argument zéro qui a-
comme premier caractère. Cela peut arriver accidentellement dans les langages de programmation comme C, où il est facile de gâcher accidentellement en oubliant de passer le nom du programme invoqué dans le cadre du tableau d'arguments àexecve
et des fonctions similaires, et si les gens oublient habituellement de se protéger contre cela, cela peut aussi finissent par être la dernière étape d'une vulnérabilité exploitable de manière malveillante qui permet à un attaquant d'obtenir un shell interactif.La ligne shebang n'a jamais été spécifiée dans le cadre de POSIX, SUS, LSB ou toute autre spécification. AFAIK, il n'a même pas été correctement documenté.
Il existe un consensus approximatif sur ce qu'il fait: prendre tout entre le
!
et le\n
etexec
lui. L'hypothèse est que tout entre le!
et le\n
est un chemin absolu complet vers l'interpréteur. Il n'y a pas de consensus sur ce qui se passe s'il contient des espaces.Heureusement, 1. et 4. semblent avoir disparu, mais 3. est assez répandu, vous ne pouvez donc tout simplement pas vous fier à pouvoir passer plus d'un argument.
Et puisque l'emplacement des commandes est également non spécifiée dans POSIX ou SUS, vous utilisez généralement jusqu'à ce seul argument en passant de l'exécutable nom de
env
sorte que il peut déterminer l'emplacement de l'exécutable; par exemple:[De toute évidence, cela suppose toujours un chemin particulier pour
env
, mais il n'y a que très peu de systèmes où il vit/bin
, donc c'est généralement sûr. L'emplacement deenv
est beaucoup plus standardisé que l'emplacement degawk
ou pire quelque chose commepython
ouruby
ouspidermonkey
.]Ce qui signifie que vous ne pouvez pas utiliser effectivement des arguments du tout .
la source
-S
commutateur qui aide ici, mais il n'est pas présent sur mon Linuxenv
, et je soupçonne qu'il n'est pas disponible sur gygwin non plus. @hstoerr, d'autres utilisateurs avec des situations différentes peuvent lire vos questions plus tard, donc en général, des réponses portables sont préférables, même si vous n'avez pas besoin de portabilité.#!/bin/sh
et/usr/bin/env gawk --re-interval -f my-script.awk
. Est-ce exact?#!
n'est pas portable. Par exemple, Windows ne reconnaît pas du tout cette convention "nativement". Un seul argument a bang est nécessaire sur Unix pour pouvoir le faire#!/usr/bin/awk -f
.#!/usr/bin/env ruby
ou les goûts.Bien que pas exactement portable, à partir de coreutils 8.30 et selon sa documentation, vous pourrez utiliser:
Alors donné:
tu auras:
et au cas où vous êtes curieux,
showargs
c'est:Réponse originale ici .
la source
Je suis tombé sur le même problème, sans solution apparente à cause de la façon dont les espaces blancs sont traités dans un shebang (au moins sous Linux).
Cependant, vous pouvez passer plusieurs options dans un shebang, du moment qu'il s'agit d' options courtes et qu'elles peuvent être concaténées (à la manière GNU).
Par exemple, vous ne pouvez pas avoir
mais tu peux avoir
De toute évidence, cela ne fonctionne que lorsque les options ont des équivalents courts et ne prennent aucun argument.
la source
Sous Cygwin et Linux, tout ce qui suit le chemin du shebang est analysé dans le programme comme un argument.
Il est possible de contourner cela en utilisant un autre
awk
script à l'intérieur du shebang:Cela s'exécutera
{system("/usr/bin/gawk --re-interval -f " FILENAME); exit}
dans awk.Et cela s'exécutera
/usr/bin/gawk --re-interval -f path/to/your/script.awk
dans votre shell système.la source
L'astuce de shébang de coquille ci-dessus est plus portable que
/usr/bin/env
.la source
python
, mais cette question concerneawk
.Dans le manuel de gawk (http://www.gnu.org/manual/gawk/gawk.html), la fin de la section 1.14 note que vous ne devez utiliser qu'un seul argument lorsque vous exécutez gawk depuis une ligne shebang. Il dit que le système d'exploitation traitera tout après le chemin de gawk comme un seul argument. Peut-être existe-t-il une autre façon de spécifier l'
--re-interval
option? Peut-être que votre script peut référencer votre shell dans la ligne shebang, s'exécuter engawk
tant que commande et inclure le texte de votre script en tant que "document ici".la source
gawk
, mais vous pouvez toujours être en mesure de diriger quelque chose vers stderr (c'est-à-dire rediriger stdout vers stderr avant de rediriger vers ce script). Je n'ai jamais vraiment essayé cela, mais tant que le premier processus n'émet rien sur stderr, cela peut fonctionner. Vous pouvez également créer un tube nommé ( linuxjournal.com/content/using-named-pipes-fifos-bash ) si vous voulez vous assurer que rien d'autre ne l'utilise.Pourquoi ne pas utiliser
bash
etgawk
lui - même, pour ignorer shebang, lire le script et le transmettre en tant que fichier à une deuxième instance degawk [--with-whatever-number-of-params-you-need]
?(-la même chose pourrait naturellement être accomplie avec par exemple
sed
outail
, mais je pense qu'il y a une sorte de beauté qui ne dépend que debash
et d'gawk
elle - même;)la source
Juste pour le plaisir: il existe la solution assez étrange suivante qui redirige stdin et le programme via les descripteurs de fichier 3 et 4. Vous pouvez également créer un fichier temporaire pour le script.
Une chose est ennuyeuse à ce sujet: le shell fait l'expansion des variables sur le script, vous devez donc citer chaque $ (comme cela est fait dans la deuxième ligne du script) et probablement plus que cela.
la source
Pour une solution portable, utilisez
awk
plutôt quegawk
, invoquez le shell BOURNE standard (/bin/sh
) avec votre shebang, et invoquezawk
directement, en passant le programme sur la ligne de commande en tant que document here plutôt que via stdin:Remarque: aucun
-f
argument pourawk
. Cela laissestdin
disponible pourawk
lire les entrées. En supposant que vous ayezgawk
installé et sur votrePATH
, cela réalise tout ce que je pense que vous essayiez de faire avec votre exemple d'origine (en supposant que vous vouliez que le contenu du fichier soit le script awk et non l'entrée, ce que je pense que votre approche shebang l'aurait traité comme ).la source