date +%Y-%m-%d_%H-%M-%S
shellcheck a maintenant une option pour auto fix
shellcheck restore.sh -f diff | git apply
Use role in script
#!/bin/bash
servers="server1;server2;server3"
IFS=';' read -r -a array <<< "$servers"
rand=$[ $RANDOM % ${#array[@]} ]
echo ${array[$rand]}
Je me mets ça de côté pour gagner du temps la prochaine fois
logfile=/tmp/logfile.log
errorfile=/tmp/error.log
function log() {
echo -e "\e[34m\e[1m[$(date +%Y-%m-%d) $(date +%H:%M:%S)] $1\e[0m" | tee -a /tmp/logfile.log
}
function logerror() {
echo -e "\e[91m\e[1m[$(date +%Y-%m-%d) $(date +%H:%M:%S)] $1\e[0m" | tee -a /tmp/logfile.log
}
log "prout"
logerror "pwet"
Ptetre qu'un jour je passerai à zsh (ohmyzsh)
En attendant je bricole
Un petit script pour check si les modules ont de nouvelles version dispo (il faut jq)
#!/bin/bash
modules=$(puppet module list|grep '\(v[0-9]\.[0-9]\.[0-9]\)')
IFS=$'\n'
for line in $modules; do
name=$(echo $line|cut -d' ' -f2)
version=$(echo $line|grep -o '\(v[0-9]\.[0-9]\.[0-9]\)'|sed 's/v//')
current_version=$(curl -s https://forgeapi.puppetlabs.com/v3/modules/${name}|jq '.current_release.version'|sed 's/"//g')
if [[ $version == $current_version ]]; then
echo "OK $name $version $current_version"
else
echo "OUTDATED $name $version $current_version"
fi
done
Je ne sais plus ou j'ai vu ça, je ne retrouve plus le lien donc je me le remets ici au cas où
#Marks
export MARKPATH=$HOME/.marks
function jump {
cd -P "$MARKPATH/$1" 2>/dev/null || echo "No such mark: $1"
}
function mark {
mkdir -p "$MARKPATH"; ln -s "$(pwd)" "$MARKPATH/$1"
}
function unmark {
rm -i "$MARKPATH/$1"
}
function marks {
ls -l "$MARKPATH" | sed 's/ / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo
}
à mettre dans son bashrc
showOriginal() {
packageName=$(dpkg -S $1|cut -d':' -f1)
tmpdir="/tmp/showOriginal-$packageName-$(date +%s)"
mkdir $tmpdir
cd $tmpir
apt-get download $packageName > /dev/null
dpkg -x *.deb $tmpdir
cat ${tmpdir}$1
cd - >/dev/null
rm -rf $tmpdir
}
jusqu'à présent j'utilisais des alias dans mon bashrc du genre :
cdbackup() { cd /home/foo/backup/; }
Mais la méthode proposée est bien plus pratique
zsh ça a l'air bien quand même. Le coup des alias inline ça rox ( gp=|grep -i )
Bien pratique pour intéragir avec le pressepapier en cmdline, exemple :
function nowplz {
xclip -i <<< $(date "+%Y-%m-%d %H:%M")
}
va copier dans le presse papier la date et l'heure actuelle
bien utile
cat liste | parallel --gnu -j 10 ssh root@{} 'ls'
Pour obtenir la diff des éléments entre deux listes :
To get the lines only in the old file:
comm -23 <(sort /tmp/oldList) <(sort /tmp/newList)
To get the lines only in the new file:
comm -13 <(sort /tmp/oldList) <(sort /tmp/newList)
comm -23 <(sort /tmp/1) <(sort /tmp/2)
comm -13 <(sort /tmp/1) <(sort /tmp/2)
Pratique pour l'écriture de script en bash lorsqu'on a besoin d'un fichier temporaire :
#Creation
tmpfile=$(mktemp)
#Utilisation...
#Clean
if [ -e "$tmpfile" ]
then
rm -f $tmpfile
fi
You can avoid this by temporarily removing the indentation for the lines of your Heredocs. However, that distorts your pretty and consistent indentation. There is an alternative. If you use <<-END instead of <<END as your Heredoc operator, Bash removes any tab characters in the beginning of each line of your Heredoc content before sending it to the command. That way you can still use tabs (but not spaces) to indent your Heredoc content with the rest of your code. Those tabs will not be sent to the command that receives your Heredoc. You can also use tabs to indent your sentinel string.
Cool stuff :
ssh user@server 'bash -s' < local_script.sh > local_script.log 2>&1
Sympa tous ces one liners ! il y a même un repo dans lequel on peut ajouter les siens : https://github.com/fxn/tkn
Mes préférés :
$ echo "!!" > script.sh
$ cp file.txt{,.bak}
$ (cd /tmp && ls)
$ nc -l 5566 > data-dump.sql
$ nc <his-ip-address> 5566 < data-dump.sql
via Olivier
function sayhello() {
echo hello
}
OR
sayhello() {
echo hello
}
Et en one-line :
sayhello() { echo hello; }
Je prefere la deuxieme solution :
function myfunc()
{
local myresult='some value'
echo "$myresult"
}
result=$(myfunc) # or result=myfunc
echo $result
Comment déclarer et itérer sur un tableau associatif en bash :
declare -A array
array[foo]=bar
array[bar]=foo
for i in "${!array[@]}"
do
echo "key : $i"
echo "value: ${array[$i]}"
done
Un truc pour faire du screencast de terminal, ça peut servir
Old mais je viens d'y repenser. Finalement je fais pareil, j'ai des mémo pour chaque commande dans un dossier de mon dropbox alors pourquoi pas essayer de les utiliser avec ça ? à tester. Dans tous les cas ça ne doit pas remplacer le man
at now +10 minutes <<< "rm -rf /tmp/tobedeleted"
at now +1 minutes <<< "init 6"
/etc/init.d/networking stop && /etc/init.d/networking start
atq
atrm 2
For multiline, consider a "HERE-doc"
at now +10 minutes <<ENDMARKER
rm -rf /tmp/tobedeleted
echo all done | mail -s 'completion notification' sysadmin@example.com
ENDMARKER
Un serveur, mais surtout un client pour faire du port knocking
screen -S machineA (ensuite on se co en ssh à machineA, puis CTRL A D pour detach)
screen -S machineB (ensuite on se co en ssh à machineB, puis CTRL A D pour detach)
etc
At the end of the day :
screen -ls affiche tous les screens (avec chacun une connexion vers le serv en ssh)
screen -r machineA pour aller sur le A
screen -r machineB pour aller sur le B
alias utiles :
alias sls='screen -ls' #Pour lister les screen
alias sr='screen -r' #Pour recover un screen
alias sn='screen -S' #Pour créer un nouveau screen
com > fic redirige la sortie standard de com dans le fichier fic,
com 2> fic redirige la sortie des erreurs de com dans le fichier fic,
com 2>&1 redirige la sortie des erreurs de com vers la sortie standard de com,
com < fic redirige l'entrée standard de com dans le fichier fic,
com1 | com2 redirige la sortie standard de la commande com1 vers l'entrée standard de com2.
Petit outil sympa qui donne l'explication de n'importe quelle commande shell (on peut c/c ce qu'on veut)l
Un wiki complet à lire sur quelques outils en bash
xargs sed cut awk grep find while for
bash# sed -i ’s/[texte_recherché]/[texte_de_remplacement]/’ monfichier.txt
Pour l’exercice nous allons dire que monfichier.txt comporte une liste d’anciennes adresses email @wanadoo.fr et que nous désirons les mettre à jour en @orange.fr .
bash# cat monfichier.txt
toto@wanadoo.fr
toto@wanadoo.fr
toto@wanadoo.fr
etc.
Donc dans ce cas, cela nous donnera :
bash# sed -i ’s/wanadoo/orange/g’ monfichier.txt
Voilà en détail l’explication :
On passe à la commande sed le paramètre “-i” pour l’édition du fichier monfichier.txt
Le paramètre “-s” (substituer) qui définit l’action de rechercher / remplacer,
l’expression régulière (REGEX),
puis le ‘g’ (action global) à la suite pour la modification de toutes les instances de la chaîne de caractères remplacer dans le fichier.
Dans le cas où on voudrait ne remplacer que la première qui aurait été trouvée, il faudra modifier comme suit : ‘s/texte1/texte2/’
Bon, cela fonctionne sur un fichier, maintenant dans le cas de plusieurs fichiers, voici la commande ‘find’ qui va compléter l’astuce.
bash# find . -maxdepth 1 -name “*.txt” -type f -exec sed -i ’s/wanadoo/orange/g’ {} \
En détail cela nous donne:
Nous utilisons la commande ‘find’ pour récupérer la liste des fichiers ‘.txt’ à traiter,
dans le dossier courant ‘.’ et de ne pas aller plus bas ‘-maxdepth 1′,
puis donc de lister les fichiers dont le nom finit par “*.txt” : ‘-name “*.txt” -type f’.
on utilise alors l’option ‘-exec’ pour dire à ‘find’ d’utiliser la commande qui suit sur les fichiers trouvés.
Et voilà, simple non ?
Site avec bon TD linux bash