3 ms·
Reading the readme, I find myself wondering what problems this solves for. The example of wrapping nano strikes me as particularly odd, since editing files is a
by MobiusHorizons 2y ago
Reading the readme, I find myself wondering what problems this solves for. The example of wrapping nano strikes me as particularly odd, since editing files is already fairly easy to do programmatically either via direct file operations or with tools like sed. Aside from editors, most tools that offer a tui also expose the functionality for programmatic access (typically with some additional flags to the same binary). So it just strikes me as the wrong abstraction to interact with most things.
The other potential goal I could imagine was automation. If that is the case, I would recommend the author to make that more clear in the examples and also to describe it in relation to `expect`, which would probably be my go to tool for such use cases.
Whatever the case it does look like a fun project, even if I don’t see any cases where it would be the right tool for the job.
- woodrowbarlow 2y agoto me this seems essentially like 'screen/tmux without the multiplexing features' which is useful because most of us do 'terminal multiplexing' via our window manager and we're really just using screen because we want to detach the process from the terminal session (e.g. as a glorified nohup wrapper). another similar tool is `nq`.
- andrewshadura 2y agoTry dtach
- ComputerGuru 2y agoThat’s “most of us who aren’t ssh’d into a remote machine” because ssh once and tmux thereafter beats ssh’ing in ever window/tab.
- mariocesar 2y agoI had this issue of needing to control Docker containers in a VPS, without sharing access to the server itself. It seems like it will be easy to create a simple web service that can communicate with the ht API, list my containers, show me the stats, and restart containers if I want to. I can manage all security in the web service. This could be a nice case.
- shanemhansen 2y agoThat would work but wouldn't making http requests to the docker socket itself be a little easier? Example: curl --silent --unix-socket /run/user/1000/docker.sock http://v1.41/version From: https://dev.to/smac89/curl-to-docker-through-sockets-1mhe https://dev.to/smac89/curl-to-docker-through-sockets-1mhe You could even do something like a reverse proxy to very limited paths although I tend to think that would ultimately be a bad idea and making your own http calls is probably better.
- mbreese 2y agoYou probably don’t want to expose that service to the internet… I see this as something like the console management for VPS. Back in the day, I remember reading about how prgmr.com had setup a console that you’d directly SSH into. That’s now this interface [1] (and a company name change), but I could see how programmatically working with this would be helpful. [1] https://tornadovps.com/documentation/vps-console https://tornadovps.com/documentation/vps-console
- radlad 2y agoThe comment you're replying to mounted the Docker daemon as a local socket, accessible only on the machine. (It exposes an HTTP server still.) I don't see why one would be any more comfortable exposing a shell to the internet than the Docker daemon. It grants _more_ capabilities. Either should likely be protected by authentication.
- mbreese 2y agoMy understanding was that there was a server running Docker containers where the admin wanted to allow others to control/start containers without giving them access to the machine through a local login. The idea proposed was to make the docker port accessible to the outside world (authenticated, somehow). I'm not sure I'd want to expose the Docker port to the outside world (or outside of a strictly firewalled subnet). Even if it is wrapped, this seems to dangerous to me. The service I talked about is not a shell. It's a command line program that operates as the shell when you login via SSH. Instead of bash/zsh/etc, this program runs instead. The purpose is to give the VM admin access for out-of-band management (serial console, reinstalling the OS, etc). I'm a big fan of this approach, where you don't necessarily get full access to the host, but you do have enough access to do the work that's needed (and still SSH encrypted). No more, no less. To me, this seems like a great approach for something like restricted VPS or container admin. I ended up doing something similar for an SSH jump box a few jobs back where you could setup some basic admin things (like uploading SSH keys) using a CLI program that was used as an SSH shell. To bring it back to the original post -- like others, I had a hard time seeing what the OP could be used for. Until I thought about this OOB CLI. It would be great for scripting access to something like this.
- colinsane 2y agohere's a terrible script which runs as root on all my boxes (as `redirect-tty /dev/tty1 unl0kr`): https://git.uninsane.org/colin/nix-files/src/commit/9189f18c1208cfc8184cbf70a202df2357bc20df/hosts/common/programs/unl0kr/redirect-tty https://git.uninsane.org/colin/nix-files/src/commit/9189f18c... none of the Linux greeters meet all my needs, so i fall back to `login`. but i still need a graphical program for actually entering in my password -- particularly because some of my devices don't have a physical keyboard (i.e. my phone). so i take the output of a framebuffer-capable on-screen-keyboard [1] and pipe that into `login`. but try actually doing that. try `cat mypassword.txt | login MobiusHorizons`. it doesn't work: `login` does some things on its stdin which only work on vtty. so instead i run login on /dev/tty1, and pipe the password into /dev/tty1 for the auth. yes, this solution is terrible. a lot of things would make it less terrible. i could fix one of the greeters to work the way i need it (tried that). i could patch `login` (where it probably won't ever be upstreamed). i could integrate the OSK into the same input system the ttys use... or i could reach for `ht`. everything except the last one is a day or more of work. 1: https://gitlab.com/postmarketOS/buffybox/-/tree/master/unl0kr https://gitlab.com/postmarketOS/buffybox/-/tree/master/unl0k...
- hitchstory 2y agoI wrote an integration testing framework which I wanted to integrate with a tool exactly like this so it could be used to, e.g. test a command line app like vim. Expect is what I tried to integrate with first. It falls over quite quickly with any kind of app that does anything mildly complicated with the terminal.
- andyk 2y agoInteresting. When we decided to build ht we didn't compare it to expect (which I hadn't heard of or used) but I'm comparing the two now as they seem related. How exactly did `expect` fall over? From what I can tell, expect does not provide the functionality of a stateful terminal server/client under the hood for you so it isn't as easy to grab "text" screenshots of a Terminal User Interface, which is one of the main motivations behind ht (will update the readme to make this main use-case more clear)
- hitchstory 2y agoScreenshots was one thing that didnt work that I needed but I think lots of control characters used by command line apps also messed up pexpect. I built my own probably not very good equivalent of your thing called icommandlib. I'm going to investigate ripping it out and replacing it with your tool.
- andyk 2y agoHey, project lead here. I had a very specific use case in mind: I’m playing with using LLM agent frameworks for software engineering - like MemGPT, swe-agent, Langchain and my own hobby project called headlong (https://github.com/andyk/headlong https://github.com/andyk/headlong). Headlong is focused on making it easy for a human to edit the thought history of an agent via a webapp. The longer term goal of headlong is collecting large-ish human curated datasets that intermix actions/observations/inner-thoughts and then use those data to fine-tune models to see if we can improve their reasoning. While working on headlong I tried out and implemented a variety of ‘tools’ (i.e., functions) like editFile(), findFile(), sendText(), checkTime(), searchWeb(), etc., which the agents call using LLM function calling. A bunch of these ended up being functions that interacted with an underlying terminal. This is similar to how swe-agent works actually. But I figured instead of writing a bunch of functions that sit between the LLM and the terminal, maybe let the LLM use a terminal more like a human does, i.e., by “typing” input into it and looking at snapshots of the current state of it. Needed a way to get those stateful text snapshots though. I first tried using tmux and also looked to see if any existing libs provide the same functionality. Couldn’t find anything so teamed up with Marcin to design and make ht. playing with the agent using the terminal directly has evolved into a hypothesis that I’ve been exploring: the terminal may be the “one tool to rule them all” - i.e., if an agent learns to use a terminal well it can do most of what humans do on our computers. Or maybe terminal + browser are the “two tools to rule them all”? Not sure how useful ht will be for other use cases, but maybe!
- MobiusHorizons 2y agoThis makes a lot of sense. I would call that out, because it's really surprising out of context. Hopefully you can see how unusual it would be to try to use human interfaces from code for which in at least the majority of cases, there are programatic interfaces for each task that already exist, and would be much less bug prone / finicky. I guess the analogy would be choosing to use Webdriver to interact with a service for which there is already an API.
- andyk 2y agodone! in the "Alternatives and related projects" section I just added to the ht readme -- https://github.com/andyk/ht/blob/main/README.md#alternatives-and-related-projects https://github.com/andyk/ht/blob/main/README.md#alternatives...
- wolrah 2y agoThe immediate thought I had upon reading the description was "this would be great for Minecraft servers". Most of us running Minecraft servers on Linux have it wrapped in screen or tmux because the CLI is the only way to issue certain commands including stopping it properly. This could provide an alternative.
- Xelynega 2y agoWhat I typically do is create a systemd service for game servers and attach a TTY. That way it starts with the rest of my web services, and linux already handles "i/o to processes" via files that other process can access(e.x. /run/minecraft/{stdin,stdout,stderr})
- wolrah 2y agoWould you mind expanding on that, or can you point me at some relevant documentation? I've never seen a systemd service example for Minecraft which allowed for sending commands to the server CLI and seeing the result without involving screen/tmux/etc. The top result on Google just doesn't allow command input at all, running the service "headless", the one on the official MC wiki uses screen, and the only other options I've seen use RCON which is neither secure nor does it show the responses you'd get on the MC console. If there's a way to run just the straight Minecraft JAR as a background service and still be able to interact with it in the occasional cases where I need to I'm very interested.
- Xelynega 2y agoBasically, you setup the standard minecraft service and then create a "socket" in systemd to use as stdin for the process(relevant documentation in systemd.socket and systemd.exec). For me this looks like -- /etc/systemd/system/minecraft.service -- [Unit] Description="Minecraft server service" [Service] Environment=JAVA_HOME="/usr/lib/jvm/java-22-openjdk" WorkingDirectory=/home/steam/minecraft/1.20.6/ ExecStart=/usr/lib/jvm/java-22-openjdk/bin/java -Xmx4096M -Xms1024M -jar /home/steam/minecraft/1.20.6/server.jar nogui User=steam Group=steam Sockets=minecraft.socket StandardInput=socket StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target -- /etc/systemd/system/minecraft.socket -- [Socket] ListenFIFO=%t/minecraft.stdin Service=minecraft.service ------------- What this will do is add a systemd dependency on minecraft.service to start minecraft.socket first(which creates the fifo `/run/minecraft.stdin`) then setup minecraft.service to listen to this socket for it's StandardInput(while leaving stdout and stderr pointing towards the journal). The service can then be started and set to automatically start on boot(`systemctl daemon-reload && systemctl enable --now minecraft`). While running, data can be written to the socket file with `echo` and redirection(e.x. `echo "help" > /run/minecraft.stdin`), and the output will be visible in the journal(`journalctl -xef --unit minecraft.service`) If you set stderr/out to go over the socket as well, then you can attach something like `screen` to it and use it like a typical TTY(or `telnet`). This uses the file `/run/minecraft.stdin` as the socket, but the documentation for systemd.socket shows that this can also be a TCP port to listen for connections(and systemd.service shows using regular files, but then you have to manually set them up).
- tstack 2y agoAs others have kinda alluded to, it could be useful for testing TUI applications. I develop a logfile viewer for the terminal (https://lnav.org https://lnav.org) and have a similar application[1] for testing, but it's a bit flaky. It produces/checks snapshots like [2]. I think the problems I run into are more around different versions of ncurses producing slightly different outputs. [1] - https://github.com/tstack/lnav/blob/master/test/scripty.cc https://github.com/tstack/lnav/blob/master/test/scripty.cc [2] - https://github.com/tstack/lnav/blob/master/test/tui-captures/tui_echo.0 https://github.com/tstack/lnav/blob/master/test/tui-captures...