linux运行vi程序命令,linux – 从haskell程序中运行vi(处理ptys)

本文探讨了如何在日志记录Shell中正确配置伪TTY(PTY),以支持交互式命令如vi正常工作。作者尝试通过调整PTY的终端属性来解决vi无法识别终端的问题,并分享了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我正在尝试编写一个日志记录

shell;例如一个捕获有关以结构化格式运行的命令的数据.为此,我使用readline读取命令,然后在子shell中执行它们,同时捕获诸如所花费的时间,环境,退出状态等内容.

到现在为止还挺好.但是,从此日志记录shell中运行诸如vi或更少内容的初始尝试失败.调查表明要做的事情是建立一个伪tty并将子shell连接到那个而不是普通的管道.这会阻止vi抱怨没有连接到终端,但仍然失败 – 我在屏幕上打印了一些废话并且命令在编辑器中作为字符打印 – 例如’ESC’只显示^ [.

我认为我需要做的是将pty置于原始模式.为此,我尝试了以下方法:

pty

parentTerminal >=

\a -> openFd a ReadWrite Nothing defaultFileFlags

sttyp

(a,b)

let rawModes = [ProcessInput,KeyboardInterrupts,ExtendedFunctions,EnableEcho,InterruptOnBreak,MapCRtoLF,IgnoreBreak,IgnoreCR,MapLFtoCR,CheckParity,StripHighBit,StartStopOutput,MarkParityErrors,ProcessOutput]

sttym = withoutModes rawModes sttyp

withoutModes modes tty = foldl withoutMode tty modes

setTerminalAttributes b sttym Immediately

setTerminalAttributes a sttym Immediately

a'

b'

return (a',b')

例如.我们得到父终端的属性,删除我认为对应于将tty设置为原始模式的各种标志(基于this code和the haddock for System.Posix.Terminal),然后在pty的两侧设置它们.

然后我使用createProcess在shell中启动一个进程,并使用waitForProcess连接到它,为子进程的stdin和stdout句柄提供pty的slave端:

eval :: (Handle,Handle) -> String -> IO ()

eval pty command = do

let (ptym,ptys) = pty

(_,_,hErr,ph)

delegate_ctlc = True,std_err = CreatePipe,std_out = UseHandle ptys,std_in = UseHandle ptys

}

snipOut

snipErr tee h stderr) hErr

exitCode

return ()

where tee :: Handle -> Handle -> IO B.ByteString

tee from to = DCB.sourceHandle from

$= DCB.conduitHandle to -- Sink contents to out Handle

$$DCB.take 256 -- Pull off the start of the stream

这肯定会改变终端设置(用stty确认),但不能解决问题.我错过了什么吗?我需要设置一些其他设备来设置属性吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值