2017-09-12 5 views
2

J'utilise System.IO.hIsTerminalDevice pour déterminer si un Handle est un terminal et appliquer une colorisation si c'est le cas. J'ai remarqué que lorsque vous traitez un processus en utilisant CreatePipe comme flux pour les nouveaux processus stdin et stdout, cette fonction renvoie True ce qui semble être la mauvaise réponse: Un tuyau ne doit pas être considéré comme un terminal. J'ai essayé de traquer le problème en regardant System.IO et System.POSIX.IO le code source mais il finit dans la fonction C pipe et me mène nulle part.Comment déterminer de manière fiable si une poignée est un terminal dans Haskell?

Y a-t-il un meilleur moyen de savoir si une poignée est un terminal? Ou est-ce que je fais quelque chose de mal?

Mise à jour

Voici 2 programmes qui sont censés exposer le comportement que j'observé:

import   Control.Monad 
import   System.IO 
import   System.Process 

main = do 
    (in_, Just out, Just err, h) <- createProcess $ (proc "./test2" []) 
            { std_in = CreatePipe 
            , std_err = CreatePipe 
            , std_out = CreatePipe } 
    dump out 
    where 
    dump h = forever $ do 
     ln <- hGetLine h 
     putStrLn ln 

Alors `test2:

import   System.IO 

main = do 
    print =<< hIsTerminalDevice stderr 
    print =<< hIsTerminalDevice stdout 
    print =<< hIsTerminalDevice stdin 

Ensuite, l'exécution du premier programme:

$ ./test 
False 
False 
False 

Je sais ce qui se passe: Ce que je suis en train de forker n'est pas le programme lui-même mais un conteneur docker ! Et j'ajoute explicitement le paramètre -t qui alloue un tty pour le conteneur ...

Répondre

3

Avez-vous un exemple minimal pour illustrer le problème? Les programme suivant « Faux », ce qui suggère que les handles avec CreatePipe sont pas mal identifiés comme appareils terminaux:

import System.Process 
import System.IO 

main = do (Just in_, Just out, err, h) <- 
      createProcess $ (shell "cat") { std_in = CreatePipe, 
              std_out = CreatePipe } 
      print =<< hIsTerminalDevice in_ 
      print =<< hIsTerminalDevice out 
+0

Le problème est pas avec les poignées retournées par 'createProcess' mais avec ceux _inside_ le processus fourchue . Comme suggéré, je vais mettre un petit exemple. – insitu

+0

J'accepte la réponse car elle m'a conduit à la solution réelle :) – insitu