Login Logout

Tips SHell

Quelques astuces SHell. Des bouts de commandes, ou simplement les arguments qui vont bien.

Configuration

Initialisation du shell

Entre les 3 modes (“login”, “interactive non-login” et “non-interactive non-login”) il y a de quoi se perdre à propos des fichiers chargés. Voici un rappel assez complet : https://github.com/rbenv/rbenv/wiki/Unix-shell-initialization

Bash history

Pour avoir un « joli » history sous Bash :

export HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoreboth:erasedups
export HISTSIZE=65535
export HISTTIMEFORMAT="%c : " 

Note : si besoin on peut chattr +a /root/.bash_history pour compliquer sa modification/suppression

Pour avoir un historique sauvegarde à chaque commande saisie et se synchronise entre plusieurs terminaux :

shopt -s histappend
PROMPT_COMMAND="history -a;history -n;${PROMPT_COMMAND}"

Changer l’éditeur de texte par défaut pour une commande

Normalement les commandes utilisant un éditeur (vipw, vigr, ldapvi, shelldap…) utilisent /etc/alternatives/editor qui est un lien symbolique vers l’éditeur par défaut du système. Sinon en ligne de commande on peut forcer la variable EDITOR :

$ EDITOR=nano vipw
$ EDITOR=pico crontab -e

Manipulations

Déplacements et effacements

La plupart des terminaux/consoles utilisent les commandes readline. Il est donc possible d’utiliser ses commandes pour faciliter le déplacement du curseur ou la suppression de caractères dans une ligne.

Déplacement :

  • Ctrl-e : avancer à la fin de la ligne
  • Ctrl-f : avancer d’un caractère
  • Ctrl-a : revenir au début de la ligne
  • Ctrl-b : revenir d’un caractère
  • Meta-b : revenir au début du mot
  • Meta-f : avancer à la fin du mot

Effacement :

  • Ctrl-k : effacer jusqu’à la fin de la ligne
  • Ctrl-u : effacer jusqu’au début de la ligne
  • Ctrl-w : effacer jusqu’au début du mot
  • Meta-d : effacer jusqu’à la fin du mot

Note : Certaines lettres sont faciles à retenir : e pour End, f pour Forward, b pour Backward.

C’est aussi valable dans tous les outils utilisant la bibliothèque “readline”, c’est à dire un grand nombre de logiciels.

Tâches de fond

Jouons sur le fond :

$ bg = "mettre en arrière plan"
$ fg = "mettre en premier plan"
$ jobs = "lister les tâches de fond"
%% = "dernier job utilisé (représenté par un +)"
%x = "job numéro x"
$ vi foo
^Z
[1]+  Stopped                 vi foo
$ tail -f bar
...
^C
$ fg
^Z
[1]+  Stopped                 vi foo
$ kill -9 %%

[1]+  Killed                 vi foo
$ ( sleep 1m; echo "Premier !" ) &
[1] 13649
$ ( sleep 30; echo "Deuxième !" ) &
[2] 13651
$ jobs
[1]-  Running                 sleep 1m && echo ...
[2]+  Running                 sleep 30 && echo ...
$ fg %2
^Z
[2]+  Stopped                 sleep 30 && echo ... 
$ jobs
[1]-  Running                 sleep 1m && echo ...
[2]+  Stopped                 sleep 30 && echo ...
$ sleep 30; bg
Premier !
[2]-  Done                    sleep 30 && echo ...
Deuxième !
$ jobs
[1]-  Done                    sleep 1m && echo ...
$ vi foo
^Z
[1]+  Stopped                 vi foo
$ exit
There are stopped jobs.
$ kill -9 %% #fg :x
$ exit

Connaître le rang d’un élément dans une liste

Avec grep :

$ ./liste_serveur.sh | grep -n NOUVEAU_SERVEUR
2:NOUVEAU_SERVEUR

Avec nl :

$ ./liste_serveur.sh | nl | grep NOUVEAU_SERVEUR
     2  NOUVEAU_SERVEUR

Avec awk :

$ ./liste_serveur.sh | awk '/NOUVEAU_SERVEUR/ { printf "%u\t%s\n", NR, $0 }'
2       NOUVEAU_SERVEUR

Ajout mot en début de chaque ligne d’un buffer

$ sed 's/^/Coucou /' <<<"$VAR"

Extraire un bloc d’un fichier

Extraire un bloc d’un fichier, de l’expression régulière <er-debut> à l’expression régulière <er-fin>.

sed -n '/<er-debut>/,/<er-fin>/p' <fichier>

Même chose en excluant <er-fin> :

sed -n '/<er-debut>/ { x; :a; H; n; /<er-fin>/ {x;p;q}; ba }' <fichier>

Avoir l’empreinte SSH d’une liste de serveurs

Pour s’assurer que le host soit connu (~/.ssh/known_hosts) et ainsi automatiser des tâches sur des serveurs même si toujours aucune connexion effectuée et acceptée :

$ (for host in machine1 machine2 ...; do echo $host; timeout -k 2 2 ssh -o 'StrictHostKeyChecking no' $host cat /etc/ssh/ssh_host_dsa_key.pub >> ~/.ssh/known_hosts; done)

Manipuler l’historique

http://www.faqs.org/docs/bashman/bashref_109.html#SEC116

Les éléments suivants permettent de rappeler des bouts des commandes précédentes. Voir la section [History Expansion(https://www.gnu.org/software/bash/manual/bash.html#History-Interaction) dans le manuel de Bash.

  • !! : la dernière commande
  • !-2 : l’avant dernière commande
  • !$ : le dernier argument de la dernière commande
  • !:2 : le deuxième argument de la dernière commande
  • ^old^new^ : le dernière commande, en remplaçant old par new

Lorsque qu’on entre une commande qui utilise l’history expansion, Bash affiche la commande qui est vraiment exécutée juste après le prompt.

Exemple :

$ echo a b c
a b c
$ !! d
echo a b c d
a b c d
$ echo !$
echo d
d
$ !-3
echo a b c
a b c

$ # copier un fichier puis l’éditer
$ cp -p file file.old
$ vi !:2
vi file

$ # lister puis extraire le contenu d’une archive
$ tar --list --file mon-archive.tar
[…]
$ ^list^extract^
tar --extract --file mon-archive.tar

Fichiers et filesystems

Ordinaire

Lister les répertoires montés sur le même FS

$ ROOT=/; get_fs(){ df $1 | tail -n1 | awk '{print $1}'; }; fs_root="$(get_fs $ROOT)"; for file in $(ls -1 $ROOT); do [ "$(get_fs $ROOT$file)" = "$fs_root" ] && echo "$ROOT$file"; done

Savoir si lignes en doublon dans un fichier

$ uniq -d <fichier>

ou autrement (appliquer un filtre différent) :

$ diff <fichier> <(cat <fichier> | uniq)

Comparer deux fichiers quant à l’existence de nouvelles lignes

$ grep -F -x -v -f <fichier1> <fichier2>

Supprimer des vieux fichiers

Si + vieux de 30 jours en modification :

$ find DIR/ -type f -mtime +30 -delete
$ find DIR/ -type f -mtime +30 -exec rm '{}' \;

Si + vieux depuis le 24 aout 2022 à 11h :

$ find DIR/ -type f ! -newermt "2022-08-24 11:00:00.00" -delete

Comparer deux fichiers à travers SSH

$ diff <fichier> <(ssh REMOTE cat <fichier>)

Lister fichiers

Lister les fichiers dont le nom contient autre chose que des lettres sans accent, des chiffres, des points ou des tirets :

find /path/ | LC_ALL=C grep -Ev '^[a-zA-Z0-9./_-]+$'

La variable LC_ALL=C évite de faire correspondre les accents, par exemple é et e.

Connaître la taille totale des derniers fichiers copiés :

$ find /path/ -type f -mtime -1  -printf "'%p' "  | xargs du -ch

Archiver

tar --create --file archive.tar --verbose -- directory
tar --create --file archive.tar --exclude='directory/subdir' --verbose -- directory
tar --create --file archive.tar --exclude='directory/subdir/*.mp3' --verbose -- directory

Lorsqu’on exclut un répertoire, il ne faut pas mettre de / à la fin du chemin.

Comparer deux fichiers avec des tabulations et des espaces :

Si un fichier est indenté avec le caractère tabulation (\t) et un autre avec 4 espaces :

diff -Et --tabsize=4 <file1> <file2>

Droits

Changer le propriétaire des fichiers selon le user

$ find /path/ -user www-user -exec chown user: '{}' \;

Changer propriétaires owner et group selon actuels

$ chown -c -R --from user:user userbis:userbis .
$ chown -c -R --from www-user:user www-userbis:userbis .

Répertoire

Surveiller les ouvertures/écritures des fichiers présents dans un répertoire

$ iwatch <target>

Savoir les différents users qui ont écrit dans /tmp

$ stat -c %U /tmp/* | sort | uniq -c | sort -n

Si « too arguments pour stat » (version plus lente) :

$ find /tmp -exec stat -c %U '{}' \; | sort | uniq -c | sort -n

Comparer deux répertoires à travers SSH

Générique :

$ DIR=$PWD
$ for file in $(rsync -rvn $DIR REMOTE:$DIR | grep -v "^skipping non-regular file" | head -n -2); do echo $DIR/$file :; diff $DIR/$file <(ssh REMOTE cat $DIR/$file); done

Pour /etc/ :

# for file in $(rsync -rvn /etc/ --exclude=*.log --exclude=ssh --exclude=ssl --exclude=.git --exclude=shadow* --exclude=gshadow* REMOTE:/etc/ | \
    grep -v "^skipping non-regular file" | head -n -2); do \
    echo /etc/$file :; diff /etc/$file <(ssh REMOTE cat /etc/$file); done

Espace disque

Attention, tune2fs -l ne rapporte pas les bonnes valeurs d’inodes libres lorsque le système de fichiers est monté.

Analyse disque

Quand il s’agit de / penser à exclure les autres partitions (si existante de toute évidence) :

# ncdu / --exclude /home --exclude /srv --exclude /var --exclude /tmp --exclude /boot --exclude /usr --exclude /proc

Pour certaines anciennes versions :

# ncdu --exclude "/home/*" /

ou plus simplement :

# du -chx / | sort -h | tail

Lister les dix plus gros fichiers réguliers sous /home :

# find /home -xdev -type f -print0 | du -h --files0-from=- | sort -hr | head

Sinon voir du côté de HowtoDUC.

Tester l’écriture disque

Simplement, en écriture (fichier de 5.1GB) :

$ dd if=/dev/zero of=test count=10000000

Lister les répertoires ayant le plus de fichiers <=> max inode

À partir de Stretch (Debian 9)

On peut utiliser la commande ncdu, et lors du listage, appuyer sur la touche c (sort by items).

À partir de Jessie (Debian 8)
$ du --inodes -x /path | sort -n
Autres versions

Sinon étapes par étapes (sans la commande du –inodes) :

PATH_TO_WATCH='/var'; RESULT_FILE='list_max_inode.txt'; TMP=$(mktemp)
#Regarder dans le premier niveau
#OLD : find $PATH_TO_WATCH -type d -printf '%p\n' | sed 's/"/\\"/g' | sed 's/^\(.*\)$/"\1"/' | while read i; do echo $(echo $i | xargs ls -a | wc -l) $i; done | sort -n > $TMP
#OLD : export IFS="
#"; for i in $(find $PATH_TO_WATCH -type d); do echo $(ls -a | wc -l) $i; done | sort -n > $TMP 
for i in $(du -x $PATH_TO_WATCH | awk '{print $2}'); do echo $(ls -1 -a $i| wc -l) $i; done  | sort -n > $TMP

#compter dans les sous niveaux
cat $TMP | (while read line; do num=$(echo $line | awk '{ print $1 }'); path=$(echo $line | awk '{ print $2 }'); echo ${path%/*}; done) | sort | uniq | (while read line; do echo $(grep "$line" $TMP | cut -f1 -d' ' | xargs echo -n | tr -s ' ' '+' | xargs echo | bc -l) $line; done) | sort -n | tee $RESULT_FILE
rm $TMP

Comprendre pourquoi résultat d’un df ne correspond pas un du

Si le résultat d’un df indique une occupation disque plus importante que lorsque on fait un du -cx /to/path, cela veut dire que sans doute un fichier a été supprimé mais est encore en lecture par un process.

On peut le rechercher en faisant :

# lsof /var/ | grep deleted

Ce qui équivaut à :

# lsof -Fn  | grep ^n/var/ | sed 's/^n//' | xargs -n1 -I file stat file | grep 'No such file or directory'

En tuant le process, la place sur le disque devrait se « libérer » et être de nouveau disponible.

Utilisateurs UNIX

Créer HOME

Si l’utilisateur existe, et qu’il est nécessaire de créer un répertoire $HOME pour ce dernier (car non existant) :

# mkhomedir_helper user

Va appliquer les bon droits sur fichiers/répertoires + copier ce qu’il y a dans /etc/skel.

Lister les utilisateurs + groupe

UNIX

$ for user in $(getent passwd | awk -F ':' '$3 > 10000 {printf $1 " "}'); do groups $user; done

LDAP

$ for user in $(getent passwd | awk -F ':' '$3 > 10000 {printf $1 " "}'); do \
    ldapsearch -x -h localhost -LLL -b "ou=people,dc=example,dc=com" cn | tail -n2 | \
    tr '\n' ' ' | cut -d':' -f2 | echo -n "$(cat <&0)"; echo = $(groups $user); done

Lister les expirations des mots de passe utilisateurs par date

LDAP

On se sert pour ça du champ sambaPwdLastSet indiquant la date du dernier changement et on y ajoute 200 jours (17280000 secondes) correspondant au champ shadowMax indiquant la durée de validité d’un mot de passe. On n’affiche pas les utilisateurs ayant leur mot de passe déjà expirés depuis plus d’un mois.

#!/bin/bash

delete_before=$(date "+%Y %b" -d -1month)

/usr/bin/ldapsearch -x -b 'ou=people,dc=XXXXXXX,dc=com' | /bin/sed '/sambaPwdLastSet\|uid:/!d' | /usr/bin/awk 'NR%2{printf "%s ",$0;next;}1' | /bin/sed -e 's/uid: //' -e 's/sambaPwdLastSet: //' | /usr/bin/xargs -L1 bash -c 'echo $(($1+17280000)); echo $0' | /usr/bin/awk 'NR%2{printf "%s ",$0;next;}1' | /usr/bin/xargs -L1 bash -c 'date -d @$0; echo $1' | /usr/bin/awk 'NR%2{printf "%s ",$0;next;}1' | /bin/sed -e "s/^\(.*\)\ \(20..\)\ \(.*\)$/- \2 \1 \3/" | /bin/sed -r -e 's/(\s+)?\S+//3' -e 's/(\s+)?\S+//6' | /usr/bin/sort -n -k 2 -k 3M -k 4 | /usr/bin/awk "/$delete_before/{p=1}p"

Serveur web

Avoir un rendu des requêtes par IP à partir d’un access.log

Selon le format, il faudra peut-être changer la valeur du field de cut (-f1 par -f2).

Compte rendu pour un laps de temps

$ date; (timeout 60 tail -f access.log | cut -d' ' -f1) | sort | uniq -c | sort -n

En direct

  • Version simple :
$ tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq -c 
  • Version couleur :
$ SEUIL=5; tail -f access.log | stdbuf -oL cut -d ' ' -f1 | stdbuf -oL uniq -c | \
eval "awk '\$1 > $SEUIL {printf \"\\033[1;31m\" \$1 \" \"  \$2 \"\\033[0m \\n\"; next;};{printf \$1 \" \" \$2 \"\\n\";}'"

Comparer les requêtes effectués dans access.log

Les différentes requêtes sont comparés aux nombres de caractères différent. La variable SEUIL est la limite de caractères différents pour 2 requêtes.

$ SEUIL=20; i=1; lastline=; cat access.log | sed 's/.*\] \(.*\)\" [0-9]\{3\}.*$/\1\"/' | \
    (while read line; do diff=$(cmp -bl <(echo "$lastline") <(echo "$line") 2>/dev/null | wc -l); \
    ((diff<SEUIL)) && ((i=i+1)) || { echo "$i $line"; i=1; }; lastline="$line"; done)

Si on veut les adresses IP, ou simplement trier le access.log avant l’analyse, il faut modifier après le : cat acccess.log |

Et si l’on considère les mots comme une seule différence (et non par caractères), on peut descendre le seuil :

$ SEUIL=3; i=1; lastline=; cat access.log | sed 's/.*\] \(.*\)\" [0-9]\{3\}.*$/\1\"/' | \
    (while read line; do diff=$(cmp -bl <(echo "$lastline") <(echo "$line") 2>/dev/null | awk '{print $1}' | \
    (compt=0; lastnumber=0; while read number; do ((lastnumber+1!=number)) && ((compt=compt+1)); lastnumber=$number; done; echo $compt)); \
    ((diff<SEUIL)) && ((i=i+1)) || { echo "$i $line"; i=1; }; lastline="$line"; done)

C’est à dire qu’entre 2 requêtes du type :

  • /page.do?pseudo=Example&pass=0322
  • /page.do?pseudo=Mail&pass=3892

il n’y a que 2 différences : le « pseudo », et le « pass ».

Analyser un apache-status

Compter le nombre de requêtes par IPs :

cat FICHIER | grep --color '<td>[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+</td>' | sed 's/.*<td>\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)<\/td>.*/\1/g' | sort -n | uniq -c | sort -n

Le faire pour un créneau horaire :

$ cd /var/www/apache-status
$ DATE=2017-10-12-14-
$ cat ${DATE}*.html | grep --color '<td>[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+</td>' | sed 's/.*<td>\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)<\/td>.*/\1/g' | sort -n | uniq -c | sort -n

Processus / Process

Pour un utilisateur

pgrep -u <user1> | xargs -r ps -F

Surveiller les nouveaux processus créés

Liste simple

$ ps -e -o etimes=,pid,cmd | sort -rn | awk '$1 != 0 && $3 !~ /^\[/'

il y a moins de X minutes

$ MIN=5; ps -e -o etimes=,pid,cmd | sort -rn | awk '{if ($1<'$(( MIN * 60 ))' && $1>0 && $3!~/\[.*\]/)  print $0 }'

Watch

Toutes les 5 secondes :

$ watch -n 5 -d "ps -e -o etimes=,pid,user,cmd | sort -n | awk '{if (\$1==0 || \$2==$$ || \$3~/watch/ || \$3~/\[.*\]/) {} else print \$0 }'"

Se baser seulement par rapport aux utilisateurs ayant créés dernièrement ces processus (SEUIL <=> processus vieux de moins de $SEUIL secondes) :

$ SEUIL=100; watch -n 5 -d "ps -e -o etimes=,user | sort -n | awk '{if (\$1<$SEUIL) print \$2 }' | sort | uniq -c | sort -n"

Cron

Recevoir le output de la commande top en cron :

top -b -d 1

Lister avec le plus de fils (/fork)

(total_procs=0; for foo in $(ps -e -o ppid | sed '1d' | sort -n | uniq -c | sort -n | awk '{ print $1 ":" $2 }'); do val=$(echo $foo | cut -d: -f1); total_procs=$((total_procs+val)); pid=$(echo $foo | cut -d: -f2); (( pid != 0 )) && { echo -n $val ') '; ps -p $pid -o pid,cmd | tail -n1; }; done; echo Total = $total_procs) | tail

Consommation Swap

(for file in /proc/*; do [ -e $file/status ] || continue; PID=$(basename $file); RES=$(grep VmSwap: $file/status | sed 's/VmSwap\:[[:space:]]*\(.*\)/\1/'); [ -n "$RES" ] && echo $RES ' = ' $PID ' ' $(ps -p $PID -o cmd --no-headers); done) | sort -n

Consommation RAM (VmSize)

$ top -o RES

Par process

$ ps o user:20,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,comm -p 3108

Par utilisateur

for var in users1 users2; do echo '#' $var ':'; ps -u $var -o pid= | while read pid; do echo -n $pid ') threads: ' "$(ps -p $pid -T | wc -l)" "; $(grep VmSize /proc/$pid/status)"; echo; vmsize=$(grep VmSize /proc/$pid/status | sed 's/^VmSize:\s*\([0-9]*\) kB/\1/'); done; done
for var in $(getent passwd | cut -d':' -f1); do echo '#' $var ':'; ps -u $var -o pid= | while read pid; do echo -n $pid ') threads: ' "$(ps -p $pid -T | wc -l)" "; $(grep VmSize /proc/$pid/status)"; echo; vmsize=$(grep VmSize /proc/$pid/status | sed 's/^VmSize:\s*\([0-9]*\) kB/\1/'); done; done

Fichiers ouverts

socket/port

  • Connaître les sockets ouvertes et ports en écoutent par un processus :
$ lsof -Pan -p PID -i
  • Connaître le pid qui écoute sur un port (2ème colonne) :
$ lsof -i :Port

Selon l’utilisateur

# lsof -u UID

Si www-data a uid=33, lister fichiers ouvert par serveur-web :

# lsof -u 33 | awk '{ print $2 " = " $9 }' | grep "/home/.*$"

Créer un fichier “dummy” de différentes tailles

Pour tester les performances d’un FTP ou autre on a besoin d’envoyer un fichier volumineux ou pas, voici comment créer un fichier vide (dummy) d’une certaine taille avec dd :

Pour un fichier de 10Mio :

$ dd if=/dev/zero of=10M.bin bs=1024 count=0 seek=$[1024*10]

Pour 100Mio :

$ dd if=/dev/zero of=100M.bin bs=1024 count=0 seek=$[1024*100]

Pour 1Gio :

$ dd if=/dev/zero of=1G.bin bs=1024 count=0 seek=$[1024*1024]

stdout / stderr

Renvoyer stdout/stderr dans une même sortie (par exemple /dev/null) :

$ eject /dev/coin > /dev/null 2>&1

Détecter les tabulations

$ grep -P '\t'

Conflit sur stdin

Rediriger stdin peut être nécéssaire, par exemple, lorsqu’on combine une boucle while read, un here-document et des commandes interactives.

Dans la boucle suivante, lorsqu’on rentre dans la boucle, la variable hostname contient bien « server1 ».

while read hostname
do
    ssh "${hostname}"
done << eof
server1
server2
eof

On peut s’attendre à ce qu’au prochain tour de boucle, hostname contienne « server2 », mais lorsque la commande ssh sera exécutée durant le premier passage de la boucle, c’est bien ssh qui va consommer la ligne « server2 » ! Pour empêcher ça, on peut faire lire un autre descripteur de fichier, comme 3, à read et envoyer le here-document dessus :

while read hostname 0<&3
do
    ssh "${hostname}"
done 3<< eof
server1
server2
eof

On peut aussi faire lire au autre descripteur de fichier à ssh à la place :

while read hostname
do
    ssh "${hostname}" 0<&3
done 3<&0 << eof
server1
server2
eof

Dans le cas particulier de ssh il y aussi l’option -n qui produit le même résultat de manière plus lisible :

while read hostname
do
    ssh -n "${hostname}"
done << eof
server1
server2
eof

Serveur mail

Avoir vision des différentes erreurs mailq (MAILER-DAEMON)

(for id in $(mailq | grep MAILER\-DAEMON | cut -d' ' -f1); do postcat -q $id| grep Diagnostic\-Code\:; done) | sort | uniq -c | sort -n

Parsing

JSON avec jq

jq est un puissant outil de manipulation de JSON en cli. Il va aussi mettre en forme et colorer en fonction du terminal.

# apt install jq

$ curl --silent ipinfo.io | jq

On peut s’en servir pour extraire certaine partie du JSON :

  • .[] : Addresser une entrée d’un tableau. Exemple “.[0]” pour la première entrée
  • .foo : Récupérer la valeur de la clée foo

Exemple : récupérer l’IP d’un container sur l’interface docker_gwbridge :

# docker inspect docker_gwbridge | jq ".[0].Containers.f37ac628a4630da4aabbd23ba8eebf9c72dce5f3ba03675515a8b3619f8425d2.IPv4Address"

Note : Pour faire des tests ou s’entrainer : https://jqplay.org/

Mot de passe

apg -c /dev/urandom -a0 -n1 -m20 -MSNCL -E oOlL10\&\\\/\"\'

Sans la commande apg :

$ tr -cd [:alnum:] < /dev/urandom | head -c22; echo

La commande echo à la fin permet d’avoir un saut de ligne. Sinon, le prompt sera collé au mot de passe qui a été généré.

En hexadecimal

Pour générer 12 charactères :

$ openssl rand -hex 6

Sans la commande openssl :

tr -cd a-f0-9 < /dev/urandom | head -c12; echo

Variables

Les variables d’environnement actuelles :

$ printenv

Ajouter une variable :

$ FOO=bar

Ajouter une variable d’environnement :

$ export FOO=bar

Supprimer une variable :

$ unset FOO

Attention, quand on utilise une variable temporaire dans une ligne de commande, elle n’est utilisée que pour l’environnement et ne peut être utiliser comme une variable. Ainsi :

$ BAR=bar echo -n foo $BAR ; BAZ=baz env | grep baz
fooBAZ=baz

Divers

Hexadécimal - décimal

$ printf '%x\n' 27
1b
$ printf '%d\n' 0x1b
27
$ bc
> obase=16
> 27
1B
$ bc
> ibase=16
> 1B
27

Tester une connexion TCP ou UDP

Si on a pas telnet(1) ou netcat(1) sous la main, on peut utiliser /dev/tcp et /dev/udp. Par exemple, pour tester une connexion à Redis :

$ exec 3<> /dev/tcp/127.0.0.1/6379
$ echo quit >&3
$ cat <&3
+OK

Un autre exemple avec HTTP :

$ exec 3<> /dev/tcp/example.com/80
$ printf 'GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n' >&3
$ cat <&3
HTTP/1.1 200 OK
[...]

Dans ces exemples, on écrit avec une commande, puis on lit avec une autre. Pour avoir un semblant d’interactivité, on peut exécuter le processus qui lit la réponse en arrière plan avant d’écrire. Par exemple avec Redis :

$ exec 3<> /dev/tcp/127.0.0.1/6379
$ cat <&3 & cat >&3
[1] 31415
auth REDACTED
+OK
quit
+OK
^C
[1]+  Done                    cat 0<&3