ECHO et guillemets, avec ou sans?
Problème:
Lorsqu'il faut enchainer les pipes (pas de jeux de mots siouplé), le formattage de sortie d'une commande doit correspondre à la commande suivante. La commande echo prend beaucoup de libertés avec les retours-chariot. Par exemple: echo $(ls) donne une suite de fichiers séparés par un espace. Il y a bien un '\n' entre chaque nom dans la variable a, mais il est transformé en ' ' par echo! En effet, chaque nom est une entrée séparée et echo ajoute son séparateur qui est l'espace.
Solution:
Les guillemets! La commande echo "$(ls)" laisse la chaîne de caractères telle quelle puisqu'il n'y a plus qu'une seule entrée.
Trier sur les champs (SORT)
Problème:
Comme j'en ai déjà parlé sur un autre fil, certains fichiers à trier sont constitués de plusieurs champs, le fichier /etc/passwd par exemple. La simple commande sort /etc/passwd donne parfois des surprises. Essayez, vous verrez.
Solution:
Demandez (gentiment) à la commande sort de trier suivant le(s) champ(s) que vous désirez (les champs doivent être consécutifs): sort -t ':' -k 1,1 /etc/passwd. Cela veut dire: trier le fichier comportant plusieurs champs séparés par ':' depuis le champ 1 jusqu'au champ 1. Cette fois-ci, le séparateur n'est pas testé comme simple caractère et le tri devient correct...
Dans la pénombre du tunnel (SSH)
Problème:
Il y a plein de services au boulot que j'aimerais utiliser à la maison, comme le mail, mais sans avoir à passer par un client web (que je déteste). Malheureusement Thunderbird n'arrive pas à s'y connecter. Normal, m'a-t-on répondu, de l'extérieur ça marche que sous Windows! :furieux:.
Solution:
Pas de panique, ssh est là. Prenons le cas du serveur SMTP: je dis à Thunderbird qu'il est assis directement dessus (localhost), à un port plus grand que 1024, pour ne pas être root chaque fois que je veux envoyer un mail.
Code:
1 2
| Server Name: localhost
Port: 1025 |
Cela est à faire une fois pour toute. Ensuite j'ouvre une connexion ssh avec l'unique ordinateur visible de la boîte, ordi_boite, avec les options magiques à chaque session où je veux envoyer un e-mail:
Code:
ssh -L 1025:smtp_server:25 jmelyn@ordi_boite
Explications:
Le client ssh à la maison écoute sur le port 1025 (vers lequel parle Thunderbird lorsque j'envoie un e-mail), transfert les données vers ordi_boite puis les renvoie vers le serveur smtp_serveur (celui qui est caché dans la boîte), port 25, celui de smtp. Maintenant j'envoie tous les mails que je veux depuis Thunderbird à la maison, et j'ai pas Windows! :pingoin2:
Single-quote or double-quote? That is the question!
Texte repris d'un fil à propos de sed: Quelles différences y a-t-il entre les chaînes délimitées par ' (single-quote) et celles délimitées par " (double-quote)?- ": à l'intérieur de double-quotes, Bash considère que c'est une chaîne de caractères à ne pas interpréter, sauf pour 4 caractères spéciaux:
- $: évaluation de 3 types d'expression:
- contenu de variable: echo "$SHELL" donne /bin/bash
- retour de commande: echo "heure: $(date +%H:%M)" donne heure: 13:00
- résultat de calcul arithmétique: echo "1 + 1 = $((1 + 1))" donne 1 + 1 = 2
- `: back-quote, echo "heure: `date +%H:%M`" est synonyme de echo "heure: $(date +%H:%M)"
- \: utilisé pour échapper (c'est-à-dire supprimer le sens spécial) les 5 caractères spéciaux suivants:
- $: echo "caractère dollar: \$" donne caractère dollar: $
- `: echo "caractère back-quote: \`" donne caractère back-quote: `
- ": echo "caractère double-quote: \"" donne caractère double-quote: "
- \: echo "caractère back-slash: \\" donne caractère back-slash: \
- retour-chariot: si un \ est en fin de ligne dans une chaîne entre " et ", alors la chaîne continue sur la ligne suivante sans ce retour-chariot. echo "ligne1, \
encore ligne 1 :-)" donne ligne 1, encore ligne 1 :-)
- !: utilisé pour l'historique des commandes. Entre double-quotes, il est impossible d'échapper ce caractère, ce sera toujours l'historique. Par exemple chez moi, echo "!ssh" donne ssh -L 1025:smtp:25 -L 1636:ldap:636 serveur.du.boulot: c'est ma dernière commande commençant par ssh.
- ': à l'intérieur de single-quotes, Bash considère que c'est une chaîne de caractères à ne pas interpréter du tout. L'interpréteur recherche simplement le second single-quote qui termine la chaîne, sans plus. Impossible donc de mettre un single-quote à l'intérieur d'une chaîne délimitée par single-quotes!
Boucle for comme en C, c'est possible?
Problème:
En langage de script en général, et en Bash en particulier, il est possible de passer en revue la liste des fichiers d'un répertoire par exemple:
Code:
1 2 3 4
| for fichier in $(echo *.c)
do
head -20 $fichier
done |
Mais lorsqu'on veut faire une action 10 fois par exemple, ça ne marche pas!
Solutions:
Une première possibilité est d'utiliser la commande seq:
Code:
1 2 3 4
| for i in $(seq 10)
do
echo "i: $i"
done |
Et la seconde possibilité est d'utiliser la syntaxe arithmétique de Bash:
Code:
1 2 3 4
| for ((i = 1; i <= 10; i++))
do
echo "i: $i"
done |
Bon, la première solution est certainement plus portable vers les autres shells...