Dans quel flux Bash écrit-il son invite?

8

J'essaie de rediriger toutes les sorties de bash (invite, entrée utilisateur, résultats) vers un fichier

Exemple:

/bin/bash > file.txt 2>&1

Je pensais que cela fonctionnerait, mais je ne reçois pas l'invite. Quelqu'un peut-il me dire ce que je fais mal?

Gilles 'SO- arrête d'être méchant'
la source

Réponses:

9

Bash affiche l'invite uniquement en mode interactif. C'est-à-dire qu'il est normalement sorti sur le terminal (/ dev / tty sur linux). Ce n'est ni / dev / stdout ni / dev / stdin :)

Maintenant, je ne suis pas sûr mais je peux imaginer que bash permettra un mode interactif limité lorsqu'il n'y a pas de terminal entièrement fonctionnel. Dans ce cas, je m'attends à ce que l'invite soit écrite sur stdout. Je n'ai pas testé ça.

Belle preuve de concept:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

affichera simplement 1..10 comme s'il n'y avait pas de redirection. Comme l'invite, la sortie est directement envoyée au terminal (qui échouera s'il n'y en a pas)

CONSEIL: si vous vouliez que tout soit collecté, regardez

sehe
la source
Conseils supplémentaires sur la façon d'obtenir potentiellement plus sortie bash dans un tube
sehe
seqest une commande externe hautement non standard et ne doit pas être utilisée de cette manière. Si vous utilisez bash, faites quelque chose comme for x in {1..10}, ou à la for ((x=1; x<=10; x++))place.
Chris Down du
: @ Chris bon point, merci pour le heads up
sehe
2

Pour vous bashfaire croire qu'il est en mode interactif (bien qu'il stdoutne soit pas envoyé à un terminal), vous pouvez utiliser la scriptcommande déjà mentionnée .

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)

la source
2

La façon la plus simple de le faire serait

bash -i >/tmp/logfile 2>&1

Bash va tout écrire /tmp/logfileet continuer d'exécuter des commandes au fur et à mesure que vous les tapez, mais rien ne sera affiché dans le terminal. Vous pouvez le faire quitter tout comme vous quittez votre session de terminal - en appuyant sur Ctrl+ Dou en tapant exit.

Notez que si vous exécutez la même chose sans stderrredirection, vous n'aurez que le message d'accueil enregistré dans le fichier, tout le reste fonctionnera dans votre terminal actuel. Ainsi, la réponse à votre question sur le flux vers lequel bash affiche son invite (et toutes les commandes suivantes) semble être: stderr .

Oh oui, et le -iparamètre force simplement bash à s'exécuter en mode interactif. N'écoutez pas ces gens - vous n'avez pas besoin de tours de magie pour le faire;)

rozcietrzewiacz
la source
+1 pour utiliser <sub>pour formater. Je viens d'apprendre quelque chose de nouveau aujourd'hui. : D
Chris K
2

L'invite est écrite sur stderr comme le montre Truss (sur Solaris ici):

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2
jlliagre
la source