Utilisation d'une variable dans une séquence de commands dans bash pour compléter une string existante – erreur de syntaxe ou design défectueuse?

J'utilise la séquence de commands suivante dans mon file .bashrc pour modifier l'apparence de mon terminal Linux. Il remplit l'écran ligne par ligne avec un motif composé de caractères. Il n'y a pas d'abstraction, les caractères proviennent d'un set dans la command elle-même:

for i in $(seq 1 $(expr $(tput lines))); do echo -en '\E[0;32m'$(tr -dc '",.o;:~' < /dev/urandom | head -c $(tput cols)); done; tput cup 1 -->the set 

L'idée principale est de lire 80 cols (octets) de certains caractères randoms de l'set, et d'imprimer ce * nombre de lignes. Maintenant, j'ai exécuté le script consortingbué suivant afin d'explorer l'ajout de nouveaux caractères à l'set. Pour maintenir la compatibilité avec le terminal Linux que j'utilise, je l'ai exécuté en dehors de X etc, avec le résultat suivant:

entrer la description de l'image ici

Je voudrais utiliser les caractères disponibles dans la séquence ci-dessus. J'ai donc pris beaucoup d'entre eux et ai fait ce qui suit, par exemple avec ◘:

 echo -n ◘ | hexdump 0000000 97e2 0098 0000003 so the UTF-8 sequence is \xE2\x97\x98 I build all the sequences I need: \xE2\x95\x99, \xE2\x95\x9a to f, \xE2\x96\x90 to 93 

Donc j'ajoute simplement à mon file .bashrc A=$(echo -e '\xE2\x97\x98') et B=$(echo -e ',.o;:~') et je modifie ma séquence de commands comme ceci (c'est-à-dire echo $A$B ):

 for i in $(seq 1 $(expr $(tput lines))); do echo -en '\E[0;32m'$(tr -dc $(echo $A$B) < /dev/urandom | head -c $(tput cols)); done; tput cup 1 

Si echo $ A ou $ B à l'invite, il imprime le caractère (s). Mais quand la séquence est appelée dans .bashrc cela ne fonctionne pas du tout. Sur un écran entier ◘ apparaît 3-5 fois au total avec de nombreux caractères generics, ce qui signifie que la sortie n'est pas prise en charge par le terme. Les autres personnages de l'set sont là. Il est intéressant de noter que si je gardais la syntaxe originale sans la variable $ B et que j'essayais simplement d'append $ A à l'set ie tr -dc '",.o'$A';:~' le même type de sortie , suggérant que c'est autre chose que la syntaxe – à cause de / dev / urandom. D'autres variations de la syntaxe utilisant des citations introduisent plus d'échos non apparentés.

Comme note de côté, dans xterm, le résultat est similaire avec différents caractères fictifs, et quelques ☗ et ◗.

Y a-t-il un moyen d'amener la variable dans l'set comme cela ou est-ce que cela doit être repensé à partir de zéro pour tenir count de ce cas?

Il s'agit d'une solution non universelle qui atteint le résultat attendu sans explorer la différence entre tr et celle de l' outil d'inheritance ou de redessiner ce que j'ai pour le moment. En tant que tel, il est défectueux mais pragmatique. Comme un consortingbuteur a fait allusion à tr , il y a une ressortingction à l'utilisation de cette command:

Actuellement, tr supporte uniquement les caractères à un seul octet. Finalement, il supportera les caractères multi-octets; quand c'est le cas, l'option -C le fera compléter l'set des caractères, alors que -c le fera compléter l'set des valeurs. Cette distinction n'a d'importance que lorsque certaines valeurs ne sont pas des caractères, ce qui n'est possible que dans les locales utilisant des encodings multi-octets lorsque l'input contient des erreurs de encoding.

Donc en fait, seuls les caractères de 1 octet à 1 octet (non Unicode) comme ceux de mon jeu initial sont pris en charge par ma séquence. J'ai également une contrainte que je rends un écran de valeur de caractères et je ne veux pas plus alors l'idée d'append un autre caractère random pour les nouveaux caractères était less attrayante, c'est-à-dire comment contrôler les caractères totaux écrits. J'ai donc décidé de postr le traitement de la sortie. La scope des caractères disponibles à utiliser comme motif sera plus petite que le nombre total de caractères d'octets disponibles, donc je peux utiliser ceux que je n'ai jamais eu l'intention d'utiliser en premier lieu et les réutiliser comme des «variables» comme ceci:

 Z1=$(echo -en '\xe2\x97\x98') \\ Z1 to Z9 will be used to Z2=$(echo -en '\xe2\x95\x9a') \\ bring in our non unicode Z3=$(echo -en '\xe2\x95\x9c') \\ chars Z4=$(echo -en '\xe2\x95\x9d') Z5=$(echo -en '\xe2\x95\x9e') Z6=$(echo -en '\xe2\x95\x9f') Z7=$(echo -en '\xe2\x96\x91') Z8=$(echo -en '\xe2\x96\x92') Z9=$(echo -en '\xe2\x96\x93') Z11="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" \\Z11 to Z13 used to Z12="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" \\reintroduce the chars Z13="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" \\used as variables tput setf 6 tput setaf 6 echo -en $(tr -dc '",.o;:~123456789a' < /dev/urandom | head -c $(echo -en "$[$(tput cols) * $(tput lines)]") | sed -e "s/1/$Z1/g" -e "s/2/$Z2/g" -e "s/3/$Z3/g" -e "s/4/$Z4/g" -e "s/5/$Z5/g" -e "s/6/$Z6/g" -e "s/7/$Z7/g" -e "s/8/$Z8/g" -e "s/9/$Z9/g" -e "0,/a/s//$Z11/" -e "0,/a/s//$Z12/" -e "s/a/$Z13/g"); tput cup 1 ^set ^^vars ^ "variables" ouput are replaced with intended char>___________________________________________________________________________________________^...then vars themselves reintroduced here as chars, one 'a' at a time(only 3 shown here, last one is global) |__________________________________________________________________________________| 

La séquence mise à jour est légèrement différente de celle du Q et est simplement rendue en un balayage propre au lieu d'une ligne par ligne. Il utilise sed et sa capacité à accepter de nombreuses commands à appliquer au stream avec -e . Les numéros 1 à 9 et la lettre "a" sont répartis au hasard dans le motif de la page entière. Le model de sortie est ensuite filtré avec sed et 1 à 9 (s'il est présent dans le stream random) sont tous convertis en nos caractères non-unicode prévus – seulement a rest. Ces "a" sont ensuite traités et utilisés pour réintroduire les caractères 1 à 9 et a lui a même dans le model en utilisant les variables Z11 à Z13 (générateur random avec tête 1 octet qui utilise 1-9 et "a" comme un set maintenant que nous don je n'en ai plus besoin). Chaque instance de a pourrait être randomisée individuellement (voir l'exemple de motif ci-dessous) ou laissée telle quelle (on peut choisir un autre caractère que "a" bien sûr, que l'on pourrait apprécier dans le motif final). Cette preuve de concept est incomplète car vous auriez finalement besoin d'intercepter tous les caractères dans cet exemple et de les transformer en quelque chose de vraiment random. Mais ça marche. Ceci est juste pour montrer ces chars (et je choisirais dans les chars de pratique que je ne veux pas utiliser dans le model donc il n'y aurait pas besoin de les réintroduire comme cela en premier lieu) peut être réintroduit. L'obstacle a été "évité".

entrer la description de l'image ici

Nous pouvons voir ce qui est arrivé aux a – le premier a été converti en 8 et le second à 1, tandis que le rest a été converti en 4s ( sed global). 1,4 et 8 étaient tous les caractères utilisés pour apporter nos caractères spéciaux, et maintenant ils peuvent être utilisés aussi au besoin. Sans doute une solution élégante existe mais ce n'est pas un de ceux-là. Tout cela est généré en un clin d'œil.

Voici une version simplifiée formatée comme un script qui utilise les numbers 1 à 9 pour notre model sans les «racheter» comme expliqué ci-dessus:

 #!/bin/bash ## spptr_dfp.sh - Display a chosen pattern of chars using tr, while using sed "post processors" to deal with ## multibyte chars that tr can't stomach. Rely on single chars not used for the pattern to bring in the ## multibyte ones later on in the pipeline. ## Z1 to Z9 will be used as primitives variables ## to bring in our non unicode chars Z1=$(echo -en '\xe2\x97\x98') Z2=$(echo -en '\xe2\x95\x9a') Z3=$(echo -en '\xe2\x95\x9c') Z4=$(echo -en '\xe2\x95\x9d') Z5=$(echo -en '\xe2\x95\x9e') Z6=$(echo -en '\xe2\x95\x9f') Z7=$(echo -en '\xe2\x96\x91') Z8=$(echo -en '\xe2\x96\x92') Z9=$(echo -en '\xe2\x96\x93') ## the color we want tput setf 6 tput setaf 6 ## the main event, generated for cols*lines ## the pattern is made out of ",.o;:~ ## the single chars used as vars are 123456789 ## after tr outputs, sed converts any of the single chars to our multibyte chars echo -en $(tr -dc '",.o;:~123456789' < /dev/urandom | head -c $(echo -en "$[$(tput cols) * $(tput lines)]") | sed -e "s/1/$Z1/g" -e "s/2/$Z2/g" -e "s/3/$Z3/g" -e "s/4/$Z4/g" -e "s/5/$Z5/g" -e "s/6/$Z6/g" -e "s/7/$Z7/g" -e "s/8/$Z8/g" -e "s/9/$Z9/g") tput cup 1 exit