Utiliser la substitution de process pour tromper les programmes en attente de files, avec des extensions spécifiques comme argument?

Voici mon cas d'utilisation: l'utilitaire de command line melt peut accepter un nom de file, avec l'extension .melt sur la command line, et l'ouvrir; à titre d'exemple, il s'agit d'un file test_p.melt correct:

 colour:blue out=24 colour:red out=48 

… qui s'ouvre et joue avec melt test_p.melt .

Maintenant, le fait est que les files .melt ne prennent pas en charge les commentaires, ce que j'aurais souhaité faire (vous obtiendrez des messages d'erreur pour toute ligne qui contient un argument inégalable, y compris ceux avec, par exemple, un # ). Voici donc un file test_c.melt commenté:

 # master comment here colour:blue # this is blue! out=24 colour:red out=48 

Ouvrir ceci dans la melt donne:

 $ melt test_c.melt Failed to load "# master comment here" ... 

… et il n'y a pas d'écran bleu montré.

J'ai donc pensé – et bien, je peux quand même mettre des commentaires, puis utiliser la substitution de process Bash pour filterr le file avec sed , et simplement le fournir à l'application de melt . Tout d'abord, essayé un test avec cat , qui est réussi:

 $ cat <(sed 's/#.*$//' test_c.melt) colour:blue out=24 colour:red out=48 

… Cela semble bon; mais , si j'essaye ça avec melt , ça se voit à travers ma supercherie:

 $ melt <(sed 's/#.*$//' test_c.melt) Failed to load "/dev/fd/62" Failed to load "/dev/fd/62" 

Fondamentalement, la fonte a obtenu le nom de file du tuyau Bash fourni pour la substitution du process – mais malheureusement, ce qui melt c'est qu'il traite argv[i] directement; et dans le cas d'un file, il doit voir une extension .melt dans le nom de file; si ce n'est pas le cas – le process échoue.

Donc, ma question est: comment pourrais-je utiliser la substitution de process – de sorte que le nom de file de la pipe a une extension spécifique, dans ce cas .melt ? Fondamentalement, à la suite de la substitution, je voudrais un nom de file pipe de /dev/fd/62.melt , qui, je pense, va passer.

NB: bien sûr, je peux toujours faire:

 sed 's/#.*$//' test_c.melt > test_c_temp.melt melt test_c_temp.melt 

… mais d'abord, il y a deux commands ici – et je voudrais un pipeline d'une ligne; et pour un autre, cela me pose un autre problème en pensant à supprimer des files temporaires par la suite, ce que je n'aime pas.

Est-ce possible avec la substitution de process Bash – ou en quelque sorte avec les outils Linux standard?

Une possibilité serait de faire pointer la melt vers un système de files qui affiche des copys modifiées de files. FUSE est un moyen générique de build un pilote de système de files implémenté par un programme ordinaire et ne nécessitant aucun privilège. Il existe de nombreux filesystems FUSE , et il y a de fortes chances pour que l'un d'entre eux puisse vous aider. L'idée est de fournir un sharepoint assembly où la lecture d'un file .melt lit le file "réel" mais avec des commentaires filtrés.

ScriptFS semble prometteur (mais je ne l'ai jamais utilisé). Quelque chose comme ça devrait fonctionner:

 mkdir ~/uncommented-melt scriptfs -p "$HOME/bin/uncomment-melt;&*.melt" ~/work ~/uncommented-melt 

~/work est la racine de l'arborescence qui contient vos files .melt et ~/bin/uncomment-melt est

 #!/bin/sh sed 's/#.*$//' "$1" 

Ensuite, si vous avez un file ~/work/test_c.melt avec des commentaires, vous pouvez lancer melt ~/uncommented-melt/test_c.melt .

Autres filesystems FUSE utiles:

  • Execfuse – vous permet de build un simple pilote FUSE avec des scripts shell
  • AVFS ou d'autres filesystems FUSE qui décompressent de manière transparente les files: définissez le décapage des commentaires en tant que règle de décompression.

Ok, il s'avère que dans mon cas particulier, ces types de scripts de fusion doivent être interprétés ssortingctement comme des arguments de command line; donc seul celui de l'OP ne le coupe pas (en plus, il y a d'autres choses comme des profils qui peuvent être définis). Donc, voici ce que j'ai fini par faire – peut probablement servir d'inspiration dans d'autres cas que le titre de l'OP couvrirait.

J'ai finalement décidé de l'utiliser: créer un file test.shmelt , qui est en fait un script bash qui contient mon code de script de melt commenté; rendre ce file exécutable chmod +x test.shmelt ; puis après avoir édité le script, exécutez-le en tant que ./test.shmelt .

Lors de l'exécution, il créera un file test.melt "nettoyé" dans /tmp , et appellera melt sur ce file à la place. Puisque melt continue à fonctionner dans le terminal après la fin de son programme, avec un piège sur SIGINT ce file temporaire peut être nettoyé quand Ctrl-C est pressé (mais pas nécessaire).

De cette façon, j'ai encore des commentaires; peut éditer rapidement dans le file source et exécuter fusion et voir les résultats; et avoir un file "nettoyé" des commentaires aussi, que je peux utiliser plus tard.

Voici le code de test.shmelt :

 #!/bin/bash # call with: ./test.shmelt #TMLTFILE="test.melt" # for final export TMLTFILE="${0%%.shmelt}.melt" # for final export function finished() { echo ; } ; # use this when testing or montaging to keep exported (tmp) .melt file; uncomment the below to remove the tmp file #~ function finished() { rm /tmp/"$TMLTFILE"; echo "fin1 $0" ; } ; trap finished SIGINT ; echo 'Remember `pulseaudio --start` to hear audio with `melt`!' pulseaudio --check if [ $? -ne 0 ]; then pulseaudio --start fi DIRNAME=$(readlink -f $(dirname $0)) PROFILE="square_ntsc" echo " # the profile doesn't work from here; # still has to be specified on command line # but including it here so the path is saved for testing #~ -profile #~ ${PROFILE} -video-track # can avoid pixmap: here, but that s the producer; # qimage: also works # NB it is NOT '-out 1645'; but 'out=1645'!! /media/myimg/%05d.bmp in=0 out=1645 #~ length=1645 #~ loop=0 #~ eof=stop -audio-track /media/mysnd/snd.wav in=0 out=1645 #~ loop=0 #~ eof=stop #-consumer xml # doesn't work here " | sed -e 's/#.*$//' -e 's/^[[:space:]]*//' -e '/^[[:space:]]*$/d' -e 's/[[:blank:]]*$//' > ${TMLTFILE} # the sed: remove comments; remove indents; remove empty lines; remove spaces at end of line # eof: one of: stop, loop, continue or pause (eof=stop) # to loop, use `melt eof=loop ...` (but make sure first, # that the edit as a whole stops - use xml to check!) # due to caching issues, preview pieces (up to ~300 frames) like this: melt eof=loop -profile ${PROFILE} ${TMLTFILE} in=200 out=400 # must have profile here, for checking w/ -consumer xml (else segfault) # this command may add additional producers to the xml!: ## melt -profile ${PROFILE} ${TMLTFILE} -consumer xml # use this to generate xml if needed: #melt -profile ${PROFILE} $(cat ${TMLTFILE} | tr '\n' ' ') -consumer xml # if exited normally, cleanup: finished