pyinvoke / invoke

Pythonic task management & command execution.
http://pyinvoke.org
BSD 2-Clause "Simplified" License
4.31k stars 365 forks source link

"Enter" key unexpected behaviour while launching a redis shell #917

Open Lotram opened 1 year ago

Lotram commented 1 year ago

I think my issue is linked to https://github.com/pyinvoke/invoke/issues/733

python: 3.10.5 invoke: 2.0.0 os: Ubuntu 20.04

I want to open a redis shell, using redis-cli.

from invoke import task

@task()
def test(context):
    context.run("redis-cli", pty=True)

The problem is the "Enter" key prints a linebreak, instead of running the Redis command.

After some digging in the code, I found out the actual execution of the command in invoke is done by os.execve(shell, [shell, "-c", command], env). If I run this line in a python shell, it works as expected, the issue only happens when running the code through runner._run_body, probably because of a problem with the thread handling.

I'd be happy to help debugging / fixing this issue, but I don't have a big understanding on how pseudo-terminals / pty / fcntl work, so I'd need some help doing this.

Lotram commented 1 year ago

After some more investigation, I found out that fix works:

from invoke.runners import Local

class CustomRunner(Local):
    def _write_proc_stdin(self, data):

        if data == b"\n":
            data = b"\r\n"

        return super()._write_proc_stdin(data)

namespace = Collection()
namespace.configure({"runners": {"local": CustomRunner}})
# namespace.add_collection(...)

I now wonder this is a problem from redis-cli because it should handle \n differently, or invoke, because it should not send \n when pressing Enter.

kuwv commented 1 year ago

@Lotram It's most definitely redis-cli as CRLF isn't really supported by any Linux system or Invoke (outside of Windows).

Lotram commented 1 year ago

Ok but then why does the shell open through invoke behave differently from the regular one / the one opened through os.execve(shell, [shell, "-c", command], env) ?

D3f0 commented 6 months ago

I've noticed this behavior in some other CLIs like fzf and k9s. The custom runner does the trick @Lotram