J'essaie de comprendre ce que fait le script Shell ci-dessous. Je sais que exec sans aucun argument redirige la sortie du shell actuel, mais je ne peux pas comprendre ce que fait la commande ci-dessous:
exec 1>/var/opt/log/my_logs/MYPROG_`date '+%Y%m%d_%H%M%S'`.log 2>&1
Il y a en fait 4 informations importantes qui se passent:
Le exec
intégré est utilisé pour rediriger toutes les sorties de la session en ligne de commande vers un fichier
Le 1><FILENAME>
indique au Shell de rediriger flux standard stdout
, c'est-à-dire que la sortie normale des commandes sans erreur passera à <FILENAME>
. Le >
sera créé si <FILENAME>
n'existe pas ou sera tronqué si <FILENAME>
existe déjà.
Le nom de fichier redirigé est créé via des backticks ajoutés avec la commande date '+%Y%m%d_%H%M%S'
. Les backticks sont sous la forme de Commande Substitution et sont fonctionnellement équivalents à la forme $(date '+%Y%m%d_%H%M%S')
, et de nos jours $(...)
est préférable pour la lisibilité et parce que cette forme peut être facilement imbriquée (c.-à-d. ) Ainsi, la sortie de date
avec le format spécifié '+%Y%m%d_%H%M%S'
créera un nom de fichier horodaté. Si votre commande a été exécutée le 4 juillet 2018 le 4 juillet à 20 h 20, le résultat sera /var/opt/log/my_logs/MYPROG_20180704_042020.log
.
2>&1
redirige le flux stderr
vers ce fichier également. Il s'agit d'un formulaire standard, conforme à POSIX (ce qui signifie que les shells de type Bourne autres que bash
le comprennent). Ceci est fonctionnellement équivalent à &>
syntaxe spécifique à bash. L'ordre des redirections spécifiées dans Shell est important, c'est pourquoi il apparaît après la redirection 1>
.
En conclusion, il ne devrait y avoir aucune sortie de cette commande elle-même. Il ne faut recâbler que deux flux de sortie de toutes les commandes successives pour aller dans le fichier que vous avez spécifié.
Fait intéressant, avec cette commande, mon bash 4.4
affiche tout dans le fichier, ce qui inclut l'invite et tout ce que je tape (je devais donc taper aveuglément echo hello world
et appuyer sur Ctrl + D pour quitter par la suite):
$ bash --posix
bash-4.4$ exec 1>./mylog_`date '+%Y%m%d_%H%M%S'`.log 2>&1
$ cat ./mylog_20180424_010800.log
bash-4.4$ echo hello world
hello world
bash-4.4$ exit
Effectuer cette opération pièce par pièce révèle que bash
affiche Invite en flux stderr
et de manière surprenante avec tout ce que je tape:
bash-4.4$ exec 1> ./mylog.txt
bash-4.4$ echo Hello World
bash-4.4$ cat ./mylog.txt
cat: ./mylog.txt: input file is output file
bash-4.4$ exec 2>&1
Dans le cas de ksh
, il se passe la même chose, mais je peux voir ce qui est saisi, seul l'invite va dans un fichier, c'est-à-dire que stdin n'est pas redirigé:
bash-4.4$ ksh
$ exec 1>./mylog 2>&1
echo hello askubuntu
bash-4.4$ cat ./mylog
$ hello askubuntu
$
bash-4.4$
Nous pouvons donc voir ici que les shells peuvent choisir de générer l'invite PS1
également vers l'un des flux standard, afin que celui-ci soit inclus dans un fichier.