I have a remote file that I edit regularly. I would like to edit it with a quick, simple command that would work likely via SSH. At present, my workflow is to connect to the remote computer via SSH, open the file using an editor (say vim or nano), edit, save and then close the connection.
I am aware that I can mount the remote computer filesystem using SSHFS or Nautilus capabilities, but I'm really looking for a single command to run in the terminal which shall open the file in an editor, allow me to save and then exit, closing all connections to the remote computer.
Currently, I am trying to do this by passing a command to the remote computer via SSH, but I am running into difficulties. For VIM, the command is something like the following:
ssh user1#computer1 "vim /path/laboratory_notebook_1.md"
Using this procedure, VIM does not run correctly and presents the following error:
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
For nano, the command is something like the following:
ssh user1#computer1 "nano /path/laboratory_notebook_1.md"
Using this procedure, nano does not run and the following error is presented:
Error opening terminal: unknown.
I'm not sure how to proceed on this line of thought. I would appreciate assistance on this method and suggestions on other ways to edit remote files briskly with a minimum amount of interaction.
Force Pseudo-TTY Allocation
You can force pseudo-tty allocation with one or more -t flags. The SSH(1) man page says:
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Example
Using your own example, slightly modified, the following would work if you have a local TTY or PTY:
ssh -t user1#computer1 'vim /path/laboratory_notebook_1.md'
It works fine for me with OpenSSH_6.2p2. Your mileage (and operating environment) may vary.
If you are using vim. Vim comes with a plugin called netrw which will allow you to do this.
vim scp://hostname/path/to/file
Will copy the file to you local machine and on save reupload it.
Take a look at netrw's documentation :h netrw
Related
In Vim, this prompts me for a password allowing me to edit a remote file:
:e scp://username#host//path
Yet, using the same command with NeoVim doesn't prompt for a password because the underlying command :! scp user#host:path LOCAL-TEMPFILE does not work interactively in NeoVim: https://github.com/neovim/neovim/wiki/FAQ#-and-system-do-weird-things-with-interactive-processes
What is the best practice to edit a remote file with NeoVim that has password authentication over ssh?
I would guess that the netrw plugin that provides this functionality isn't installed / active for Neovim. Check whether the :Nread command is available. Compare the :scriptnames output from Vim and Neovim. Read the plugin's documentation :help pi_netrw for how to install and enable it.
Update: So, it turns out that there's an Neovim issue with interactive commands started from :!, and this is what netrw is doing; the plugin does not capture the password challenge. It's basically executing :! scp user#host:path LOCAL-TEMPFILE
If you can avoid the issue (use key-based SSH authentication for the hosts), you could continue to use Neovim with netrw. If this is really important to you, more elaborate workarounds are possible. (For example, I use a wrapper around ssh that parses ~/.ssh/config for custom Password Hunter2 entries (these passwords are well known in the org and only used for testing VMs, so no security issue here), and then uses sshpass to automatically log in.)
Else, you have to switch to classic Vim for netrw operations, or use another way of accessing these remote files (e.g. SSHFS).
When I'm on my own computer's terminal, when I enter the command vim filename and vim opens the file in the terminal.
When I log into my school account using SSH, and I enter vim filename, nothing happens.
I assume it's trying to open it using XQuartz, which I recently uninstalled.
How do I make it open in the terminal window, like on my own computer?
I have tried not using -Y when logging on, but it doesn't make a difference.
Actually, there is a workaround. You can try to edit it using the scp option in Vim.
Just run vim scp://user#schoolserver.edu/path/to/your/file from your terminal and you'll start editing the file using Vim from your local machine.
If you want to learn more about scp in Vim type :help scp in Vim.
I'd like to change my terminal color depending on ssh connected HOSTNAME.
I know how to modify the terminal, but how can I instrument ssh to add hooks?
I could wrap the ssh command with a shell function, or replace the binary, but its used as a dependency by other apps, and I would rather not do that.
You can use LocalCommand feature of OpenSSH when connecting to a remote server:
LocalCommand
Specifies a command to execute on the local machine after successfully connecting to the server. The command string extends to the end of the line, and is executed
with the user's shell. The following escape character substitutions will be performed: ‘%d’ (local user's home directory), ‘%h’ (remote host name), ‘%l’ (local host
name), ‘%n’ (host name as provided on the command line), ‘%p’ (remote port), ‘%r’ (remote user name) or ‘%u’ (local user name).
The command is run synchronously and does not have access to the session of the ssh(1) that spawned it. It should not be used for interactive commands.
This directive is ignored unless PermitLocalCommand has been enabled.
There is probably no easy way to execute a command when ending a connection with a remote server though apart from writing a ssh wrapper.
A Wrapper around SSH may be your best bet, even though you have discounted it. However almost every program lets you specify the 'ssh' command they use.
In my I own case I have a 'r' command to replace 'ssh' which performs account lookups (username and host aliases and DNS expansion without relying on the 'DNS resolver domain list', amoungst other things). These Are my notes to get various programs to call 'r' instead of 'ssh'.
scp
No config or environment variables, you must use option "-Sr"
scp -Sr ...
rsync
set environment variable
RSYNC_RSH="r -x"
unison
In ".unison/default.prf"
sshcmd = r
sshargs = -q -x
cssh
In ".clusterssh/config"
ssh=r
ssh_args= -x -o ConnectTimeout=10
multixterm
Use multixterm -xc "r %n" hostname...
vim netrw (file explorer)
Have it use the "rsync" command (set above)...
vim rsync://hostname/
OR for vim scp://hostname/...
In ".vimrc" configuration, redefine scp command to use.
let g:netrw_list_cmd="r USEPORT HOSTNAME ls -Fa1"
let g:netrw_scp_cmd="scp -Sr -q"
My 'r' script decodes all SSH arguments, I have seen used, and even handles very OLD "rsync" commands that placed more options AFTER the hostname! (Yes, I have been using this script a long time)
I have a remote file that I edit regularly. I would like to edit it with a quick, simple command that would work likely via SSH. At present, my workflow is to connect to the remote computer via SSH, open the file using an editor (say vim or nano), edit, save and then close the connection.
I am aware that I can mount the remote computer filesystem using SSHFS or Nautilus capabilities, but I'm really looking for a single command to run in the terminal which shall open the file in an editor, allow me to save and then exit, closing all connections to the remote computer.
Currently, I am trying to do this by passing a command to the remote computer via SSH, but I am running into difficulties. For VIM, the command is something like the following:
ssh user1#computer1 "vim /path/laboratory_notebook_1.md"
Using this procedure, VIM does not run correctly and presents the following error:
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
For nano, the command is something like the following:
ssh user1#computer1 "nano /path/laboratory_notebook_1.md"
Using this procedure, nano does not run and the following error is presented:
Error opening terminal: unknown.
I'm not sure how to proceed on this line of thought. I would appreciate assistance on this method and suggestions on other ways to edit remote files briskly with a minimum amount of interaction.
Force Pseudo-TTY Allocation
You can force pseudo-tty allocation with one or more -t flags. The SSH(1) man page says:
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Example
Using your own example, slightly modified, the following would work if you have a local TTY or PTY:
ssh -t user1#computer1 'vim /path/laboratory_notebook_1.md'
It works fine for me with OpenSSH_6.2p2. Your mileage (and operating environment) may vary.
If you are using vim. Vim comes with a plugin called netrw which will allow you to do this.
vim scp://hostname/path/to/file
Will copy the file to you local machine and on save reupload it.
Take a look at netrw's documentation :h netrw
Although I have never tried this, it is apparently possible to remotely edit a file in vim as described here. In my particular case the server I need access to can only be accessed from on campus, hence I have to log into my university account like so:
ssh user#login.university.com
then from there log into the secure server like so:
ssh user#secure.university.com
I have keyless ssh set up, so I can automate the process like so:
ssh user#login.university.com -t "ssh user#secure.university.com"
is there anyway to remotely edit a file such as secure.university.com/user/foo.txt on my local machine?
EDIT:
My intention is to use vim on my local machine as it is impractical (move .vim folder, copy .vimrc) and in some cases impossible (recompile vim with certain settings, patch vim source, install language beautifiers) to make vim on the remote machine behave the way I want it to behave. What I want is to issue something like this (this is not accurate scp, I know)
vim scp://user#login.university.com scp://user#secure.university.com//home/user/foo.txt
OK after a little working around I figured it out. First you have to edit (or create) your .ssh/config file as described here. For our purposes, we will add a line like this, which essentially adds a proxy.
Host secure
User Julius
HostName secure.university.com
ProxyCommand ssh Tiberius#login.university.com nc %h %p 2> /dev/null
Then we can simply copy (via scp) the file secure.university.com:/home/Julius/fee/fie/fo/fum.txt to the local computer like so
scp secure:/home/Julius/fee/fie/fo/fum.txt fum.txt
Extending on this, we can load it into vim remotely like so:
vim scp://secure//home/Julius/fee/fie/fo/fum.txt
or using badd like so:
:badd scp://secure//home/Julius/fee/fie/fo/fum.txt
To simplify my life, I added this shortcut to my .vimrc file for the most commonly used subfolder:
nnoremap <leader>scp :badd scp://secure//home/Julius/fee/fie/fo/fum.txt
So far vim has proven to be pretty aware that this is a remote file, so if the C file includes a file like so:
#include "foo.h"
it won't complain that "foo.h" is missing
Once you SSHed in the machine you can run any command(also vim) in remote host on your shell. After logging run vim as you are running in your machine.
Since you are using ssh, you basically have access to the server via the CLI, as if you were sitting in front of the machine itself. With that said, you can use any program on that machine, just like you would use it on your own machine. Assuming that the secure.university.com/user/foo.txt means that there is a text file called foo.txt at location /user on the secure server, then the following commands would work after logging in through ssh:
cd /user
vim foo.txt
You could also use nano or any other CLI based editor that is installed on the machine.