J'ai écrit un script simple qui echo
-es son PID:
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
J'exécute ledit script (il dit 3844
encore et encore) dans un terminal et j'essaie tail
le descripteur de fichier dans un autre:
$ tail -f /proc/3844/fd/1
Il n'imprime rien à l'écran et se bloque jusqu'à ^c
. Pourquoi?
De plus, tous les descripteurs de fichiers STD (IN / OUT / ERR) sont liés aux mêmes points:
$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14
Est-ce normal?
Exécuter Ubuntu GNOME 14.04.
Si vous pensez que cette question appartient à SO ou SU au lieu d'UL, dites-le.
Réponses:
Faire un
strace
detail -f
, il explique tout. La partie intéressante:Ce qu'il fait? Il configure un
inotify
gestionnaire du fichier, puis attend que quelque chose se produise avec ce fichier. Si le noyau dit àtail
travers ce gestionnaire inotify, que le fichier a changé (normalement, a été ajouté), alorstail
1) cherche 2) lit les modifications 3) les écrit à l'écran./proc/3844/fd/1
sur votre système est un lien symbolique vers/dev/pts/14
, qui est un périphérique de caractères. Il n'y a rien de tel que certains comme une "carte mémoire", qui pourrait être accessible par cela. Ainsi, il n'y a rien dont les modifications pourraient être signées dans l'inotify, car il n'y a pas de zone de disque ou de mémoire accessible par cela.Ce périphérique de caractères est un terminal virtuel, qui fonctionne pratiquement comme s'il s'agissait d'une prise réseau. Les programmes exécutés sur ce terminal virtuel se connectent à cet appareil (comme si vous vous connectiez telnet à un port tcp) et écrivent dans quoi ils veulent écrire. Il y a aussi des choses plus complexes, par exemple le verrouillage de l'écran, les séquences de contrôle de terminal et autres, celles-ci sont normalement gérées par des
ioctl()
appels.Je pense que vous voulez en quelque sorte regarder un terminal virtuel. Cela peut être fait sur linux, mais ce n'est pas si simple, il a besoin de certaines fonctionnalités de type proxy réseau et d'un peu d'utilisation délicate de ces
ioctl()
appels. Mais il existe des outils qui peuvent le faire.Actuellement, je ne me souviens pas quel paquet Debian a l'outil pour atteindre cet objectif, mais avec un peu de recherche sur Google, vous pourrez probablement le trouver facilement.
Extension: comme @Jajesh l'a mentionné ici (donnez-lui un +1 si vous me l'avez donné), l'outil est nommé
watch
.Extension # 2: @kelnos a mentionné, un simple
cat /dev/pts/14
était également suffisant. J'ai essayé cela, et oui, cela a fonctionné, mais pas correctement. Je n'ai pas beaucoup expérimenté avec cela, mais il me semble que si une sortie entrant dans ce terminal virtuel est allée soit à lacat
commande, soit à son emplacement d'origine, et jamais aux deux. Mais ce n'est pas sûr.la source
tail
est correcte (le bit de veille inotify), mais il est incorrect en ce qu'il est en fait très simple de faire ce que vous voulez: utilisez simplement à lacat
place detail
.cat
ne fonctionne pas non plus pour moi, il se bloque de la même manière que la queue et tout ce que je peux faire est de le fairectrl+c
.echo $$
pourecho $$ >> foo
maintenant il y a un fichier et le processus l'ouvre et l'ajoute toutes les 0,5 secondes. Je ne peux toujours pas y accéder via le descripteur de fichier et tous les descripteurs de fichiers/proc/$pid/fd/
(mais 254 qui sont liés autest.sh
script lui-même) sont liés/dev/pts/14
. Comment bash y accède-t-foo
il?Les fichiers dans
/dev/pts
ne sont pas des fichiers normaux, ce sont des poignées pour les terminaux virtuels. Unpts
comportement de lecture et d'écriture n'est pas symétrique (c'est-à-dire que ce qui y est écrit peut être lu ultérieurement, comme un fichier normal ou un fifo / pipe), mais médiatisé par le processus qui a créé le terminal virtuel: certains courants sont xterm ou ssh ou agetty ou screen. Le processus de contrôle enverra généralement des pressions de touches aux processus qui lisent lepts
fichier et rendra à l'écran ce qu'ils écrivent sur lepts
.Ainsi,
tail -f /dev/pts/14
imprimera les touches que vous appuyez sur le terminal à partir duquel vous avez commencé votre script, et si vous le faites,echo meh > /dev/pts/14
lemeh
message apparaîtra dans le terminal.la source
tail -f /dev/pts/14
n'imprime pas les touches que je tape sur ce terminal. C'est une réponse intéressante, cependant. Merci.Il y a quelque temps j'ai trouvé un peu contournement qui parfois répond à la nécessité de vérifier ce qui est à STDOUT émis, supposant que vous avez un
pid
du processus et vous pouvez nu les yeux résultats hostiles:la source
Je suppose que pour cela plutôt que de suivre, ce que vous devez faire serait de regarder la sortie.
J'espère que c'est ce dont vous avez besoin.
la source
watch
. Ce que j'essaie de faire est de jeter un œil à la sortie du processus déjà en cours, doncwatch
ça n'aide pas.