Taper /usr/bin/env sed -f
dans les travaux terminaux.
Mais si vous l'utilisez comme un shebang,
#!/usr/bin/env sed -f
s/a/b/
Le script ne pourra pas être exécuté:
/usr/bin/env: sed -f: No such file or directory
Je pense que c'est lié au -f. Mais comment résoudre cela?
scripting
sed
executable
env
Cheng
la source
la source
Réponses:
Vous ne pouvez pas, de manière portative, mettre plus d'un argument sur une
#!
ligne . Cela signifie seulement un chemin complet et un argument (par exemple#!/bin/sed -f
ou#!/usr/bin/sed -f
), ou#!/usr/bin/env
et aucun argument à l'interpréteur.Une solution de contournement pour obtenir un script portable consiste à utiliser
#!/bin/sh
un wrapper shell, en passant le script sed comme argument de ligne de commande. Notez que ceci n'est pas autorisé par POSIX (les scripts multi-instructions doivent être écrits avec un-e
argument séparé pour chaque instruction pour la portabilité), mais cela fonctionne avec de nombreuses implémentations.Pour un long script, il peut être plus pratique d'utiliser un hérédoc. Un avantage d'un hérédoc est que vous n'avez pas besoin de citer les guillemets simples à l'intérieur, le cas échéant. Un inconvénient majeur est que le script est alimenté par sed sur son entrée standard, avec deux conséquences ennuyeuses. Certaines versions de sed nécessitent
-f /dev/stdin
au lieu de-f -
, ce qui pose un problème de portabilité. Pire, le script ne peut pas agir comme un filtre, car l'entrée standard est le script et ne peut pas être les données.L'inconvénient de l'hérédoc peut être corrigé par une utilisation utile de
cat
. Dans la mesure où cela place à nouveau l'intégralité du script sur la ligne de commande, il n'est pas compatible POSIX, mais largement portable en pratique.Une autre solution consiste à écrire un script qui peut être analysé à la fois par sh et par sed. C'est portable, assez efficace, juste un peu moche.
Explications:
b
; le contenu n'a pas d'importance tant que la fonction est syntaxiquement bien formée (en particulier, vous ne pouvez pas avoir de fonction vide). Ensuite, si vrai (c'est-à-dire toujours), exécutezsed
le script.()
étiquette, puis une entrée bien formée. Ensuite, unei
commande, qui n'a aucun effet car elle est toujours ignorée. Enfin l'()
étiquette suivie de la partie utile du script.la source
#!/usr/bin/env
et aucun argument." n'est pas très bien formulé. Peut-être "ou#!/usr/bin/env sed
et aucun argument pour sed."Il existe différentes implémentations incompatibles du shebang (#!) Selon le système d'exploitation. Certains construisent une liste complète d'arguments, certains préservent le chemin de commande et mettent tous les arguments restants en un seul, certains ignorent tous les arguments et ne transmettent que le chemin de commande, et enfin, certains passent la chaîne entière comme un seul commander. Vous semblez être dans ce dernier cas.
la source
env essaie de trouver un fichier avec le nom "sed -f". Vous pouvez essayer "#! / Usr / bin / sed -f" comme ligne de shebang.
la source
Depuis GNU coreutils v8.30 , vous pouvez faire:
Cette fonctionnalité a été ajoutée dans une récente (20/04/2018) engage à
env.c
dans le paquet de GNU, qui a ajouté la-S
ou--split-string
option.Depuis la
env
page de manuel:D'autres exemples sont disponibles dans le manuel GNU coreutils .
Si vous utilisez également l'
-v
option pour une sortie détaillée, vous pouvez voir exactement commentenv
fractionne la chaîne d'arguments:Dans
my_sed_script.sed
:Exécution:
Remarque: Cela ne s'applique qu'aux shebangs qui utilisent
/usr/bin/env
, comme--split-string
c'est une caractéristique de GNU enenv
particulier.la source
Cette réponse fournit un chemin vers une solution élégante: /programming//a/1655389/642372
read
un hérédoc dans une variable shell.sed
.Échantillon:
la source
J'aime la solution de Walker, mais elle peut être améliorée (en mettant cela dans une réponse séparée car les commentaires n'acceptent pas le texte préformaté). Cela peut ne pas fonctionner sur toutes les versions de Linux ou de Bash, mais sur Ubuntu 17.10, vous pouvez le réduire comme suit:
Vous pouvez supprimer
eval
et simplifier laread
commande, mais vous devez vous débarrasser du commentaire dans l'hérédoc.De plus, pour tout ce que vous avez toujours voulu savoir sur sed mais que vous aviez peur de demander, il y a un tutoriel très utile sur http://www.grymoire.com/unix/sed.html . Cela suggère une solution encore meilleure, au détriment de la perte
/usr/bin/env
et du codage en dur du chemin vers sed:Cela présente l'avantage supplémentaire de prendre en charge plusieurs
s///
remplacements.la source