wiki/TipsShell.md

272 lines
6.1 KiB
Markdown
Raw Normal View History

2016-12-21 19:32:52 +01:00
# Astuces SHell
2017-03-28 10:42:28 +02:00
## Script
2016-12-21 19:32:52 +01:00
2017-03-28 10:42:28 +02:00
Style guide : <https://google.github.io/styleguide/shell.xml>
2017-01-03 09:15:29 +01:00
2017-03-28 10:42:28 +02:00
## Configuration
2017-01-20 10:33:36 +01:00
2017-03-28 10:42:28 +02:00
### Initialisation du shell
2017-01-20 10:33:36 +01:00
2017-03-28 10:42:28 +02:00
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>
2017-01-24 11:50:40 +01:00
2017-03-28 10:42:28 +02:00
### History Bash
2017-01-24 11:50:40 +01:00
`bashrc` :
~~~
export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoreboth
export HISTSIZE=65535
export HISTTIMEFORMAT="%c : "
~~~
> *Note* : si besoin on peut `chattr +a /root/.bash_history` pour empêcher sa suppression
2017-03-14 12:22:58 +01:00
2017-03-28 10:42:28 +02:00
### Changer l'éditeur de texte par défaut pour une commande
2017-03-14 12:22:58 +01:00
2017-03-14 12:23:31 +01:00
Normalement le script (vipw, vigr, -ldapvi, ...) se réfère aux fichiers scripts (qui ne sont que des liens vers les binaires) :
2017-03-14 12:22:58 +01:00
~~~{.bash}
/etc/alternatives/
~~~
Sinon en ligne de commande :
~~~{.bash}
$ EDITOR=nano vipw
~~~
2017-03-28 10:42:28 +02:00
## Manipulations
2017-03-15 12:01:56 +01:00
2017-03-28 10:42:28 +02:00
### Tâches de fond
2017-03-15 12:01:56 +01:00
~~~{.bash}
$ 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"
~~~
~~~{.bash}
$ 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
2017-03-15 12:04:20 +01:00
[1]- Running sleep 1m && echo ...
[2]+ Running sleep 30 && echo ...
2017-03-15 12:01:56 +01:00
$ fg %2
^Z
2017-03-15 12:04:20 +01:00
[2]+ Stopped sleep 30 && echo ...
2017-03-15 12:01:56 +01:00
$ jobs
2017-03-15 12:04:20 +01:00
[1]- Running sleep 1m && echo ...
[2]+ Stopped sleep 30 && echo ...
2017-03-15 12:01:56 +01:00
$ sleep 30; bg
Premier !
2017-03-15 12:04:20 +01:00
[2]- Done sleep 30 && echo ...
2017-03-15 12:01:56 +01:00
Deuxième !
$ jobs
2017-03-15 12:04:20 +01:00
[1]- Done sleep 1m && echo ...
2017-03-15 12:07:25 +01:00
$ vi foo
^Z
[1]+ Stopped vi foo
$ exit
There are stopped jobs.
$ kill -9 %% #fg :x
$ exit
2017-03-15 12:39:56 +01:00
~~~
2017-03-28 10:42:28 +02:00
## Fichiers et FS
2017-04-07 11:20:35 +02:00
### Ordinaire
#### Savoir si lignes en doublon dans un fichier
2017-03-28 10:42:28 +02:00
~~~{.bash}
$ uniq -d <fichier>
~~~
ou autrement (appliquer un filtre différent) :
~~~{.bash}
$ diff <fichier> <(cat <fichier> | uniq)
~~~
2017-04-07 11:20:35 +02:00
#### Comparer deux fichiers quant à l'existence de nouvelles lignes
2017-03-28 10:42:28 +02:00
~~~{.bash}
$ grep -F -x -v -f <fichier1> <fichier2>
~~~
2017-04-07 11:20:35 +02:00
#### Supprimer des vieux fichiers
2017-03-15 12:39:56 +01:00
2017-04-07 11:20:35 +02:00
- Par exemple, si + vieux de 30 jours en modification :
2017-04-04 11:35:43 +02:00
2017-04-07 11:20:35 +02:00
~~~{.bash}
$ find DIR/ -type f -mtime +30 -delete
$ find DIR/ -type f -mtime +30 -exec rm '{}' \;
2017-04-04 11:35:43 +02:00
~~~
2017-04-07 11:43:55 +02:00
#### Comparer deux fichiers à travers SSH
~~~{.bash}
$ diff <fichier> <(ssh REMOTE cat <fichier>)
~~~
2017-04-07 11:20:35 +02:00
### Répertoire
2017-04-07 11:20:35 +02:00
#### Surveiller les ouvertures/écriture des fichiers présent dans un répertoire
2017-03-15 17:41:23 +01:00
~~~{.bash}
$ iwatch <target>
~~~
2017-04-07 11:20:35 +02:00
#### Savoir les différents users qui ont écris dans /tmp
~~~{.bash}
2017-03-15 16:17:03 +01:00
$ stat -c %U /tmp/* | sort | uniq -c | sort -n
2017-03-16 10:37:53 +01:00
~~~
2017-04-07 11:43:55 +02:00
#### Comparer deux répertoires à travers SSH
Générique :
~~~{.bash}
$ DIR=$PWD
2017-04-07 11:46:43 +02:00
$ 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
2017-04-07 11:43:55 +02:00
~~~
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 \
2017-04-07 11:46:43 +02:00
echo /etc/$file :; diff /etc/$file <(ssh REMOTE cat /etc/$file); done
2017-04-07 11:43:55 +02:00
~~~
2017-04-07 11:20:35 +02:00
### Espace et Inode
#### 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
~~~
Pour certaines anciennes versions :
~~~
# ncdu --exclude "/home/*" /
~~~
Sinon voir du côté de [HowtoDUC](/HowtoDUC).
#### Tester l'écriture disque
2017-03-16 10:37:53 +01:00
Simplement, en écriture (fichier de 5.1GB) :
~~~{.bash}
$ dd if=/dev/zero of=test count=10000000
2017-03-21 11:45:57 +01:00
~~~
2017-04-07 11:20:35 +02:00
#### Lister les répertoires ayant le plus de fichiers <=> max inode
2017-03-28 10:42:28 +02:00
~~~{.bash}
PATH_TO_WATCH='/var'
RESULT_FILE='list_max_inode.txt'
TMP=$(mktemp)
#Regarder dans le premier niveau
(for i in $(find $PATH_TO_WATCH -type d); do echo $(ls -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
~~~
2017-04-05 14:42:17 +02:00
## Utilisateurs UNIX
### Lister les utilisateurs + groupe
2017-04-05 14:48:22 +02:00
#### UNIX
2017-04-05 14:42:17 +02:00
~~~{.bash}
$ for user in $(getent passwd | awk -F ':' '$3 > 10000 {printf $1 " "}'); do groups $user; done
~~~
2017-04-05 14:48:22 +02:00
#### LDAP
2017-04-05 15:58:31 +02:00
~~~{.bash}
2017-04-05 15:58:47 +02:00
$ for user in $(getent passwd | awk -F ':' '$3 > 10000 {printf $1 " "}'); do \
2017-04-07 11:22:33 +02:00
ldapsearch -x -h localhost -LLL -b "dc=MACHINE,dc=DOMAIN,dc=COM" cn | tail -n2 | \
2017-04-05 15:58:31 +02:00
tr '\n' ' ' | cut -d':' -f2 | echo -n "$(cat <&0)"; echo = $(groups $user); done
~~~
2017-04-05 14:48:22 +02:00
2017-03-28 10:42:28 +02:00
## Serveur web
### Avoir un rendu des requêtes par IP à partir d'un access.log
2017-03-21 11:45:57 +01:00
2017-03-21 12:07:28 +01:00
Avoir un compte rendu pour un laps de temps :
~~~
# date; (timeout 60 tail -f /var/log/apache2/access.log | cut -d' ' -f1) | sort | uniq -c | sort -n
~~~
Ou regarder les IPs en direct :
2017-03-21 16:44:00 +01:00
- Version simple :
2017-03-21 12:07:28 +01:00
~~~
# tail -f /var/log/apache2/access.log | stdbuf -oL cut -d ' ' -f1 | uniq -c
2017-03-21 16:44:00 +01:00
~~~
- Version couleur :
~~~
# SEUIL=5; tail -f /var/log/apache2/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\";}'"
2017-03-21 17:24:13 +01:00
~~~
2017-03-28 10:42:28 +02:00
## Process
### Un processus par rapport à une socket/port
2017-03-21 17:24:13 +01:00
- Connaître les sockets ouvertes et ports en écoutent par un processus :
~~~{.bash}
$ lsof -Pan -p PID -i
~~~
- Connaître le pid qui écoute sur un port (2ème colonne) :
~~~{.bash}
$ lsof -i :Port
2017-03-28 10:27:52 +02:00
~~~
2017-04-06 12:35:32 +02:00
### Surveiller les nouveaux processus créés
- Lister simplement :
~~~{.bash}
$ ps -e -o etimes=,pid,cmd | sort -rn | awk '{if ($1!=0 && $3!~/\[.*\]/) print $0 }'
~~~
- Watch :
2017-04-06 12:47:43 +02:00
2017-04-06 12:53:57 +02:00
Toutes les 5 secondes :
2017-04-06 12:47:43 +02:00
~~~{.bash}
2017-04-06 12:53:57 +02:00
$ watch -n 5 -d "ps -e -o etimes=,pid,cmd | sort -n | awk '{if (\$1==0 || \$2==$$ || \$3~/watch/ || \$3~/\[.*\]/) {} else print \$0 }'"
2017-04-06 12:47:43 +02:00
~~~