Samedi 31 août 2019

Cher Journal,

Noyé au milieu d'un fil de discussion de plus à propos des usages non nécessaires de la commande cat, un courriel utile de la part de Teemu Likonen s'est démarqué :

For the command and information ordering discussion I'll remind that
shell redirections can be placed also before the command. Commands

    $ cat input | command

can be replaced with

    $ <input command

-- Teemu Likonen, on debian-user

C'est cool, car ça veut dire que ce genre de construction, dans laquelle l'entrée se trouve tout à gauche du pipeline et la sortie tout à droite, est permise sans multipiler les appels à cat :

< entrée.txt commande1 | commande2 | commande3 > sortie.txt

Voici un petit exemple d'utilisation, pour voir ce que ça donne dans la pratique. Admettons qu'un traitement soit nécessaire sur le fichier HEADER.html :

$ <HEADER.html _

Disons par exemple que formater le contenu en commentaire de langage de script classique soit nécessaire, ça se ferait avec la commande sed :

$ <HEADER.html sed -E 's/^(.*)$/# \1/' _

Pour voir le résultat sans saturer le terminal, la commande head peut être ajoutée afin de tronquer le résultat de la commande sed dans le dataduc :

$ <HEADER.html sed -E 's/^(.*)$/# \1/' | head -n 3
# <h1>
# Samedi 31 août 2019
# </h1>
$ _

À première vue, cette notation semblait sympathique pour les règles de rédaction où une ligne ne doit comprendre qu'une commande, mais finalement ça ne s'y prête pas forcément très bien. En séparant le fichier d'entrée et la première commande, le pipe ne doit pas y apparaître, ce qui est visuellement curieux, voir piégeur d'un point de vue rédactionnel :

< HEADER.html \
  sed -E 's/^(.*)$/# \1/' \
| head -n 3 \
> sortie.txt

Note à moi-même, ce serait pas mal de corriger ce bug dans le convertisseur de flux RSS, qui me mange mes caractères backslash, ainsi que le saut de ligne qui suit ; les utilisateurs du flux ne vont pas comprendre le propos sinon.

À comparer avec l'usage de la commande cat, qui dans ce cas donnerait :

cat HEADER.html \
| sed -E 's/^(.*)$/# \1/' \
| head -n 3 \
> sortie.txt

Ou alors en utilisant la capacité de sed à lire les fichiers qui lui sont passés en argument :

sed -E 's/^(.*)$/# \1/' HEADER.html \
| head -n 3 \
> sortie.txt

La question de l'équilibre visuel et logique est délicate, car est notamment dépendante des points de vue, et devrait être appliquée, ou non, en fonction de la situation rencontrée.

Suite à une remarque additionnelle de Jonas Smedegaard, de l'autre côté du spectre existe une commande sponge, qui prend son entrée standard pour l'enregistrer dans un fichier passé en argument. Avec la construction ci-dessus, cela donnerait :

cat HEADER.html \
| sed -E 's/^(.*)$/# \1/' \
| head -n 3 \
| sponge sortie.txt

Cette approche a un certain mérite en ce sens que le nombre de signes cabalistiques spécifique au Shell se réduit au tube, ou pipe, inventé par notre cher Doug McIlroy. Une remarque à noter est que cette commande ne fait pas partie des utilitaires de base de Debian, mais peut être installée via le paquet moreutils, qui comprend tout un tas de commandes très simples mais néanmoins aux propriétés très intéressantes, notamment :

Mais bon, les commandes fournies par moreutils ne sont pas disponibles partout, ce qui nuit à la portabilité des scripts ainsi obtenus. Pour un usage interactif cependant, beaucoup peuvent être très pratiques, notamment les éditeurs de textes pour éditer l'arborescence de fichier, ou les pipes. :)

Une dernière note pour la fin : la pratique de positionner le fichier d'entrée en tout début de commande avec la redirection est peu commune dans les scripts en Bourne Shell qui peuvent être rencontrés dans la nature. L'ajouter abusivement pourrait augmenter la difficulté à maintenir un script donné.

[ICO]NameLast modifiedSize
[PARENTDIR]Parent Directory  -
[TXT]sortie.txt2019-08-31 22:08 38

  —