GNU/Linux >> Tutoriels Linux >  >> Linux

Bash Echo La ligne de commande exécutée sur la ligne de commande elle-même (pas dans un script) ?

À des fins de documentation, je veux dire rediriger vers le fichier stdout et stderr à partir d'une commande que j'exécute.
Par exemple, je lancerais (ma commande est moins triviale que l'alias ll mais cela n'a probablement pas d'importance):

$ ll > out-err.dat 2>&1
$ cat out-err.dat
drwxr-xr-x 39 us00001 us00001    4096 jul 31 14:57 ./
drwxr-xr-x  3 root    root       4096 feb  2 06:06 ../
-rw-------  1 us00001 us00001   62226 jul 31 11:56 .bash_history
...

Également à des fins de documentation, je souhaite stocker dans le même fichier de sortie la ligne de commande que j'ai utilisée.
Le comportement et la sortie prévus sont

$ [NEW COMMAND LINE]?
$ cat out-err.dat
[NEW COMMAND LINE]   <- This first line would contain the command line used
drwxr-xr-x 39 us00001 us00001    4096 jul 31 14:57 ./
drwxr-xr-x  3 root    root       4096 feb  2 06:06 ../
-rw-------  1 us00001 us00001   62226 jul 31 11:56 .bash_history
...

Comment cela peut-il être fait ?
Je sais que je pourrais écrire un script bash et l'exécuter, de sorte que la commande resterait documentée séparément.
Je pourrais en outre écrire un script pour faire écho à la ligne de commande dans le fichier, puis l'exécuter avec une redirection vers le même file.
Je recherche une solution possible sans script.

MODIFIER  :
Feedback sur une belle réponse.
Cela ne correspondrait pas à un commentaire.

J'ai testé avec la commande echo_command ll echo_command.sh ../dir > out-err.dat 2>&1 .

Script echo_command.sh , dont je source , contient les définitions des fonctions.

../dir est un répertoire inexistant, pour forcer une sortie vers stderr .

Méthode 1 :
Fonctionne bien, sauf pour deux problèmes :

  • Il ne comprend pas les alias (ll dans ce cas; lors du remplacement par ls ça a marché).

  • Il n'enregistre pas la partie de redirection.

Méthode 2 :
Ça ne marche pas très bien. Maintenant, la partie de redirection est également imprimée, mais la ligne de commande est imprimée à l'écran au lieu d'être redirigée vers le fichier.

MODIFIER :
Retour sur un commentaire posté, à propos d'un script utilitaire.
Il est assez polyvalent, encore plus avec scriptreplay .

script peut être appelé seul, ce qui produit un shell interactif (il ne conserverait pas l'historique récent du shell parent)

Il peut également être appelé comme script -c <command> <logfile> . Cette dernière forme correspond à l'objectif de l'OP, mais elle ne stocke pas la commande elle-même dans le fichier journal. Il produit (au moins dans les cas de base) la même sortie que <command> > <logfile> 2>&1 .

Il semble donc que cela ne soit pas utile ici.

Réponse acceptée :

Vous pouvez utiliser une fonction comme celle-ci :

echo_command() { printf '%sn' "${*}"; "${@}"; }

Exemple :

$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux

Comme l'a dit Tim Kennedy, il y a aussi un script très utile commande :

$ script session.log
Script started, file is session.log
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done, file is session.log
$ cat session.log
Script started on 2018-07-31 16:30:31-0500
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit

Script done on 2018-07-31 16:30:43-0500

Mettre à jour

Si vous avez également besoin de consigner les redirections et essentiellement chaque syntaxe shell (notez que j'ai ajouté une petite Command line: message pour identifier facilement la commande en cours d'exécution) :

echo_command() {
  local arg
  for arg; do
    printf 'Command line: %sn' "${arg}"
    eval "${arg}"
  done
}

Tenez simplement compte du fait que vous devez être très prudent avec la citation comme eval est utilisé :

$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo

Il accepte également plusieurs commandes à la fois au lieu d'une seule :

$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz

Linux
  1. Astuces Bash pour tous les jours en ligne de commande

  2. La commande "eval" dans Bash ?

  3. Passer les arguments de la ligne de commande au script Bash ?

  4. Comment voir la ligne de commande exacte en cours d'exécution dans une instance Bash ?

  5. Génération d'un hachage SHA-256 à partir de la ligne de commande Linux

Maîtrisez la ligne de commande Linux

Est-il possible de faire interagir un script shell bash avec un autre programme en ligne de commande ?

Lire ligne par ligne dans le script bash

Imprimer la sortie de l'instruction cat dans la boucle de script bash

À quoi sert $# dans Bash

Exécutez la commande bash sur le pipeline jenkins