Bash
Startup
Des raccourcis utiles
- Ctrl + a : Pour aller au début de la ligne
- Ctrl + e : Pour aller à la fin de la ligne
- Ctrl + b : Pour se déplacer d'un caractère vers l'arrière (flèche gauche)
- Ctrl + f : Pour se déplacer d'un caractère vers l'avant (flèche droite)
- Alt + b : Pour se déplacer d'un mot vers l'arrière
- Alt + f : Pour se déplacer d'un mot vers l'avant
- Ctrl + xx : Pour passer de la position du curseur au début de la ligne et revenir à la position où se trouvait le curseur
- TAB : Pour compléter automatiquement les noms de fichiers/dossiers/commandes
- Ctrl + d : Pour effacer le caractère sur lequel se trouve le curseur
- Ctrl + h : Pour effacer le caractère précédant le curseur (la fonction classique du retour arrière)
- Alt + d : Pour effacer le mot suivant le curseur
- Alt + retour arrière : Pour effacer le mot précédant le curseur
- Ctrl + l : Pour nettoyer l'écran (l'équivalent de la commande clear)
- Alt + t : Pour échanger la place du mot où se trouve le curseur avec celui le précédant
- Ctrl + t : Pour échanger la place des deux caractères précédant le curseur
- Ctrl + w : Pour couper le mot précédant le curseur
- Ctrl + k : Pour couper la partie de la ligne suivant le curseur
- Ctrl + u : Pour couper la partie de la ligne précédant le curseur
- Ctrl + y : Pour coller la dernière chose coupée
- Ctrl + _ : Pour annuler la dernière modification (undo)
- Ctrl + j : Pour créer une nouvelle ligne
- Ctrl + c : Pour arrêter la commande en cours et créer aussi une nouvelle ligne
- Ctrl + r : Pour rechercher une commande précédente dans l'historique
- Ctrl + g : Pour quitter la recherche dans l'historique
- Ctrl + p : Commande précédente (flèche haut)
- Ctrl + n : Commande suivante (flèche bas)
- Ctrl + x + e : Pour lancer un traitement de texte (nano par ex.) pour écrire une longue commande.
La dernière commande
- !! : Pour répéter la dernière commande
- alt + . : Pour ajouter le dernier argument de la dernière commande
$ vim todo.txt $ mv [alt + .]todo.txt ~/tmp
- !$ : Egalement utile pour ajouter le dernier argument de la dernière commande
- !* : Pour reproduire tous les arguments de la dernière commande
C'est utile si vous faites une erreur du genre : $ vim cd ~/downloads $ !* ce qui donnera $ cd ~/downloads
- !foo : Pour réutiliser la dernière commande en commençant par foo (on peut aussi faire foo !!)
- !:- : Pour réutiliser la dernière commande sans le dernier argument
Un exemple: $ ping -c 3 linuxfr.org $ !:- framasoft.org Ce qui donnera $ ping -c 3 framasoft.org
- A ces commandes, vous pouvez ajouter à la fin :p (par ex. !*:p) pour afficher la commande sans qu'elle se lance.
Builtin
See all bash builtins. Type the following command:
$ help $ help | less
Substitution
Summary: String Manipulation and Expanding Variables
For your ready references here are all your handy bash parameter substitution operators.
${parameter:-defaultValue} Get default shell variables value
${parameter:=defaultValue} Set default shell variables value
${parameter:?"Error Message"} Display an error message if parameter is not set
${#var} Find the length of the string
${var%pattern} Remove from shortest rear (end) pattern
${var%%pattern} Remove from longest rear (end) pattern
${var:num1:num2} Substring
${var#pattern} Remove from shortest front pattern
${var##pattern} Remove from longest front pattern
${var/pattern/string} Find and replace (only replace first occurrence)
${var//pattern/string} Find and replace all occurrences
Setting Up Default Shell Variables Value
The syntax is as follows:
${parameter:-defaultValue}
var=${parameter:-defaultValue}
If parameter not set, use defaultValue.
Setting Default Values
The syntax is as follows:
${var:=value}
var=${USER:=value}
The assignment ( := ) operator is used to assign a value to the variable if it doesn't already have one.
Display an Error Message If $VAR Not Passed
If the variable is not defined or not passed, you can stop executing the Bash script with the following syntax:
${varName?Error varName is not defined}
${varName:?Error varName is not defined or is empty}
${1:?"mkjail: Missing operand"}
MESSAGE="Usage: mkjail.sh domainname IPv4" ### define error message
_domain=${2?"Error: ${MESSAGE}"} ### you can use $MESSAGE too
This is used for giving an error message for unset parameters.
Find Variable Length
You can easily find string length using the following syntax:
${#variableName}
echo ${#variableName}
len=${#var}
Remove Pattern (Front of $VAR)
The syntax is as follows:
${var#Pattern}
${var##Pattern}
The first syntax removes shortest part of pattern and the second syntax removes the longest part of the pattern.
Remove Pattern (Back of $VAR)
The syntax is as follows:
${var%pattern}
${var%%pattern}
Exactly the same as above, except that it applies to the back of $var.
Find And Replace
The syntax is as follows:
${varName/Pattern/Replacement}
${varName/word1/word2}
${os/Unix/Linux}
To replace all matches of pattern, enter :
out="${x//unix/linux}"
Substring Starting Character
The syntax is as follows:
${parameter:offset}
${parameter:offset:length}
${variable:position}
var=${string:position}
Expands to up to length characters of parameter starting at the character specified by offset.
Autocomplete SSH host
complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh scp sftp
PV
Copier un fichier avec progression pv Pour copier un fichier, on va utiliser uniquement la commande pv :
pv fic-source > fic-dest
Ce qui donne par exemple :
pv Fedora-Cinnamon-Live-x86_64-24_Beta-1.6.iso > copie.iso 1.28GiO 0:00:02 [ 529MiB/s] [==========================>] 100%
Créer une clé USB bootable avec dd et pv Pour créer une clé USB (/dev/sdc) bootable d'une ISO Linux, la commande est :
dd if=fichier-image-linux.iso of=/dev/sdc
Dorénavant, on peut utiliser avec pv pour avoir une progression de l'avancement de la copie :
pv fichier-image-linux.iso | dd of=/dev/sdc
Ce qui donne en fin de copie ceci : (Imaginer le curseur ===⇒ avancer au cours de la copie)
pv fichier-image-linux.iso | dd of=/dev/sdc 1,41GiO 0:00:54 [26,5MiB/s] [=======================================================>] 100% 2965504+0 enregistrements lus 2965504+0 enregistrements écrits 1518338048 octets (1,5 GB) copiés, 54,5804 s, 27,8 MB/s
Créer une archive compressée .tar.gz Coupler tar et pv est possible, utiliser comme ceci :
tar -czf - dossier | pv > archive.tar.gz
Décompresser une archive .tar.gz Pour décompresser, même principe que la compression, mais à l'envers :
pv sox.tar.gz |tar xzf - /code> ===== Rm except ===== * Delete all file except file1 <code>rm !(file1)
- Delete all file except file1 and file2
rm !(file1|file2)
- Delete all file except all zip files
rm !(*.zip)
- Delete all file except all zip and iso files
rm !(*.zip|*.iso)
- You set full path too
rm /Users/vivek/!(*.zip|*.iso|*.mp3)
- Pass options
rm [options] !(*.zip|*.iso)
rm -v !(*.zip|*.iso)
rm -f !(*.zip|*.iso)
rm -v -i !(*.php)
Return codes
| Exit Code | Description |
|---|---|
| 0 | Success |
| 1 | Operation not permitted |
| 2 | No such file or directory |
| 3 | No such process |
| 4 | Interrupted system call |
| 5 | Input/output error |
| 6 | No such device or address |
| 7 | Argument list too long |
| 8 | Exec format error |
| 9 | Bad file descriptor |
| 10 | No child processes |
| 11 | Resource temporarily unavailable |
| 12 | Cannot allocate memory |
| 13 | Permission denied |
| 14 | Bad address |
| 15 | Block device required |
| 16 | Device or resource busy |
| 17 | File exists |
| 18 | Invalid cross-device link |
| 19 | No such device |
| 20 | Not a directory |
| 21 | Is a directory |
| 22 | Invalid argument |
| 23 | Too many open files in system |
| 24 | Too many open files |
| 25 | Inappropriate ioctl for device |
| 26 | Text file busy |
| 27 | File too large |
| 28 | No space left on device |
| 29 | Illegal seek |
| 30 | Read-only file system |
| 31 | Too many links |
| 32 | Broken pipe |
| 33 | Numerical argument out of domain |
| 34 | Numerical result out of range |
| 35 | Resource deadlock avoided |
| 36 | File name too long |
| 37 | No locks available |
| 38 | Function not implemented |
| 39 | Directory not empty |
| 40 | Too many levels of symbolic links |
| 42 | No message of desired type |
| 43 | Identifier removed |
| 44 | Channel number out of range |
| 45 | Level 2 not synchronized |
| 46 | Level 3 halted |
| 47 | Level 3 reset |
| 48 | Link number out of range |
| 49 | Protocol driver not attached |
| 50 | No CSI structure available |
| 51 | Level 2 halted |
| 52 | Invalid exchange |
| 53 | Invalid request descriptor |
| 54 | Exchange full |
| 55 | No anode |
| 56 | Invalid request code |
| 57 | Invalid slot |
| 59 | Bad font file format |
| 60 | Device not a stream |
| 61 | No data available |
| 62 | Timer expired |
| 63 | Out of streams resources |
| 64 | Machine is not on the network |
| 65 | Package not installed |
| 66 | Object is remote |
| 67 | Link has been severed |
| 68 | Advertise error |
| 69 | Srmount error |
| 70 | Communication error on send |
| 71 | Protocol error |
| 72 | Multihop attempted |
| 73 | RFS specific error |
| 74 | Bad message |
| 75 | Value too large for defined data type |
| 76 | Name not unique on network |
| 77 | File descriptor in bad state |
| 78 | Remote address changed |
| 79 | Can not access a needed shared library |
| 80 | Accessing a corrupted shared library |
| 81 | .lib section in a.out corrupted |
| 82 | Attempting to link in too many shared libraries |
| 83 | Cannot exec a shared library directly |
| 84 | Invalid or incomplete multibyte or wide character |
| 85 | Interrupted system call should be restarted |
| 86 | Streams pipe error |
| 87 | Too many users |
| 88 | Socket operation on non-socket |
| 89 | Destination address required |
| 90 | Message too long |
| 91 | Protocol wrong type for socket |
| 92 | Protocol not available |
| 93 | Protocol not supported |
| 94 | Socket type not supported |
| 95 | Operation not supported |
| 96 | Protocol family not supported |
| 97 | Address family not supported by protocol |
| 98 | Address already in use |
| 99 | Cannot assign requested address |
| 100 | Network is down |
| 101 | Network is unreachable |
| 102 | Network dropped connection on reset |
| 103 | Software caused connection abort |
| 104 | Connection reset by peer |
| 105 | No buffer space available |
| 106 | Transport endpoint is already connected |
| 107 | Transport endpoint is not connected |
| 108 | Cannot send after transport endpoint shutdown |
| 109 | Too many references |
| 110 | Connection timed out |
| 111 | Connection refused |
| 112 | Host is down |
| 113 | No route to host |
| 114 | Operation already in progress |
| 115 | Operation now in progress |
| 116 | Stale file handle |
| 117 | Structure needs cleaning |
| 118 | Not a XENIX named type file |
| 119 | No XENIX semaphores available |
| 120 | Is a named type file |
| 121 | Remote I/O error |
| 122 | Disk quota exceeded |
| 123 | No medium found |
| 125 | Operation canceled |
| 126 | Required key not available |
| 127 | Key has expired |
| 128 | Key has been revoked |
| 129 | Key was rejected by service |
| 130 | Owner died |
| 131 | State not recoverable |
| 132 | Operation not possible due to RF-kill |
| 133 | Memory page has hardware error |
Tests (BATS)
Lorsque que l'on écrit le script suivant foo.sh:
#!/usr/bin/env bash
foo() {
echo "Hello World!"
}
foo
exit 1
on peut écrire un fichier de test test.bats:
#!/usr/bin/env bats
@test "test sur l'output dans stdout" {
run bash foo.sh
[ "${lines[0]}" = "Hello World!" ]
}
@test "test sur l'exit code" {
run bash foo.sh
[ "$status" -eq 0 ]
}
et lancer la commande:
bats test.bats
Cela fournit le résultat suivant:
✓ test sur l'output dans stdout
✗ test sur l'exit code
(in test file test.bats, line 10)
`[ "$status" -eq 0 ]' failed
2 tests, 1 failure
Version comparison
#!/bin/bash
vercomp () {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 2
fi
done
return 0
}
