Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSH kitten and command with glob #1787

Closed
lithammer opened this issue Jul 8, 2019 · 8 comments
Closed

SSH kitten and command with glob #1787

lithammer opened this issue Jul 8, 2019 · 8 comments

Comments

@lithammer
Copy link

As suggested by the FAQ, you can use the kitten to automatically copy the terminfo to the remote user like so:

kitty +kitten ssh myserver

Now, I'm running Fish shell and figured I would create a wrapper function for this (maybe this was a bad idea to begin with?):

# ~/.config/fish/functions/ssh.fish
function ssh -d 'kitty compatible ssh command'
    switch $TERM
    case xterm-kitty
        kitty +kitten ssh $argv
    case "*"
        command ssh $argv
    end
end

My problem is that this breaks Fish's tab completion for remote files for the scp command. And it basically boils down to this part:

kitty +kitten ssh -o 'BatchMode yes' example.com /bin/ls -dp \*
/bin/ls: cannot access '*': No such file or directory

Same command using ssh directly:

command ssh -o 'BatchMode yes' example.com /bin/ls -dp \*
404.jpg
src/
temp/

It seems like the kitten is treating * literally, instead of a glob on the remote.

@kovidgoyal
Copy link
Owner

The kitten has nothing to do with completion. THat is carried out by the
shell. I am guessing fish has sme special casing for the ssh command
when doing completion. It does not know about the ssh kitten.

@kovidgoyal
Copy link
Owner

What you can do is look in complete.py where the completion code for the kitty command sits, and add some special casing for the ssh kitten to delegate to the fish shells ssh completion function (if that is possible). I'm not a fish users, so I cant help more than that.

@lithammer
Copy link
Author

lithammer commented Jul 9, 2019

Sorry, I think maybe I wasn't clear. The completion isn't the problem, it was just a demonstration of how the problem can manifest (or rather how I initially ran into it). Fish shell populates the complete list for remote scp files using ssh -o 'BatchMode yes' $host /bin/ls -dp \*, and I created my own function shadowing ssh that calls kitty +kitten ssh (as I demonstrated).

The problem is that kitty +kitten ssh is parsing/using command-line arguments different from ssh(1), regardless of shell. As you can see from my examples, normally the * is expanded on the remote server, while the kitten is treats it as a literal * and the command fails.

But maybe it's just my assumption that's wrong that kitty +kitten ssh could be used as a drop-in replacement.

@kovidgoyal
Copy link
Owner

To test that run the command in question manually and see what you get. The ssh kitten tries hard to preserve command line compat with ssh. It should be a drpoo in replacement in most contexts.

@lithammer
Copy link
Author

lithammer commented Jul 9, 2019

Did some digging. And it seems like 05d51d8 caused a regression(?) while attempting to fix #730.

However it seems like that issue still isn't fixed since I'm still getting issues on 0.14.2:

$ kitty +kitten ssh hostname 'echo hello'
bash: line 63: exec: echo hello: not found

Anyway, I'm probably missing something, but I tried to remove the quoting that happens to the arguments passed to exec:

diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py
index 6e7a2714..3988bade 100644
--- a/kittens/ssh/main.py
+++ b/kittens/ssh/main.py
@@ -101,8 +101,7 @@ def main(args):
         terminfo = subprocess.check_output(['infocmp']).decode('utf-8')
         sh_script = SHELL_SCRIPT.replace('TERMINFO', terminfo, 1)
         if len(server_args) > 1:
-            command_to_execute = ["'{}'".format(c.replace("'", """'"'"'""")) for c in server_args[1:]]
-            command_to_execute = 'exec ' + ' '.join(command_to_execute)
+            command_to_execute = 'exec ' + ' '.join(server_args[1:])
         else:
             command_to_execute = ''
         sh_script = sh_script.replace('EXEC_CMD', command_to_execute)

And now both scenarios work:

# Issue 730
$ python3 -m ssh.main example.com 'echo hello'
hello

# This issue
$ python3 -m ssh.main example.com /bin/ls -dp \*
404.jpg
src/
temp/

# Literal match for *
$ python3 -m ssh.main example.com /bin/ls -dp '\*'
/bin/ls: cannot access *: No such file or directory

@kovidgoyal
Copy link
Owner

well without that, for example:

kk ssh echo '"'

will echo part of the script.

@kovidgoyal
Copy link
Owner

I dont know what ssh is doing to make ssh 'echo hello' work but as far as I know, it should not work, since you are executing the program 'echo hello' not the program echo with the argument hello. Not sure what a good solution for this is.

@kovidgoyal kovidgoyal reopened this Jul 9, 2019
@lithammer
Copy link
Author

Excellent! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants