7

I found myself in a situation where I needed to connect (with ssh) to a remote machine where there were no text editors installed (no ed, ex, vi or nano).  This is on a running production server.  We don't install (and don't allow) text editors, basically because of the beliefs:

  • you don't really need them.
  • leaving them out probably adds to security as well.

However, you still need to debug and troubleshoot from time to time.

The shell is Bash.  The only way that I can see to edit text files is to use echo and cat.

Can you please share your experience of how would you edit text files in such a situation?  Perhaps there is a way to pipe a file to local vim?

Update: To clarify, the question is more just a theoretical case. A couple of times I had to debug pods in a k8 cluster with very minimal setup. So you may need to update some configs.

mrded
  • 209
  • 1
  • 2
  • 6

10 Answers10

8

In that instance, I'd try transferring files out and editing them on another computer, then transfer them back. If you have ssh, you should have scp (I hope), so you should be able to push files in and out. If not, you can also look for ftp to transfer files in and out.

If not, then I think your best option is to try and make use of cat, grep, sed, echo, and I/O redirection (especially append with >>). And lots of temporary files.

Kusalananda
  • 333,661
faxeyo
  • 81
  • If the SFTP protocol is enabled, you can even mount the FS remotely with sshfs and edit the files directly from the machine with proper editors. – Stéphane Chazelas Aug 21 '20 at 15:00
  • It's what I was hoping, if I can make a tunnel to a file and exit it locally. Can I do it with just ssh? – mrded Aug 27 '20 at 16:22
4

As faxeyo mentioned, the easiest way to edit the file is to edit it remotely. Vim on your local machine often is able to edit files over SFTP, and if you use some other editor, it may be able to work remotely as well.

However, maybe you're editing a file that can only be modified as some other user and that won't work. If the remote system is a Linux system, it may have busybox on it, and some versions of busybox include vi and ed. The vi will not be fully featured, but it will be functional enough to edit files. You can invoke these with busybox vi FILE or busybox ed file. You may be able to scp over a statically linked busybox binary as well.

Your system may have a somewhat more functional ed binary elsewhere. It's a line editor much like the colon commands of vi (the ex commands). While optional on many Linux distros, it's often used for some of the more esoteric features of patch, so it may be present. ed and the ex mode of vi also have the pleasant feature of working without a TTY.

Some very old Debian systems have ae, which can run in vi mode. Every other non-Linux open source operating system I'm aware of has one of vi, ex, or ed in the base system and don't permit them to be removed via their package manager.

If there really are no text editors, I'd write chunks of data with cat and heredocs into temporary files and edit mistakes with sed. I'd also send a nice email to the sysadmin (from another system, of course), asking if they could kindly install an editor or two.

bk2204
  • 4,099
  • 7
  • 9
  • Thank you, for your replay. We don't have text editors basically because on a running production server, you don't really need it. And probably it adds to security as well.

    However, you still need to debug and troubleshoot it from time to time. So we edit it in chunks with cat, as you mentioned.

    – mrded Aug 27 '20 at 16:13
  • None of ae, ex, ed, vi available. – mrded Aug 27 '20 at 16:19
3

If zsh is installed, you can edit the files with the zsh line editor with:

zmodload zsh/mapfile
vared 'mapfile[myfile.txt]'

Or even:

autoload zed
zed myfile.txt
2

I was working on Router with BusyBox installed and it didn't provided any text editor. One of the ways I was able to achieve it was,

  1. Output the file content using cat
  2. Edit the files on your system/pc
  3. Upload the updated file on internet such as Transfer.sh
  4. Download the updated file on the router/device using curl command, in my case I had to use the --ignore switch as well to bypass certificate/https warning.
  5. Remove [RM] the old file.
  6. Rename/Move [MV] the new file with the old files' name.
Gagan
  • 21
2

This is not the answer to your question, and it may still help someone with the same question. I looked for the workarounds of this Q/A and did not need them in the end. And I want to share this after some wasted time spent on this.

I did not see the elephant in the room. Just install vim: apt-get install vim. In my container, this worked, no need to add the installer to the image. And this should work anywhere else where you have the rights to install.

2

If there is no editor available and all the other ways that this could be made to work (install/compile, download, file transfer,..) are unavailable..

..you can still just cat the file, edit it at your leisure elsewhere and then echo "content" > file.txt. Of course, you need to have linebreaks in your content and copy and paste needs to be available.

If there is no paste, either, you have a lot of typing to do to make this work.

Ocean
  • 272
1

can use scp in one command to edit remotely a file on local vim:

vim scp://user@host//path/to/file

Note the // is mandatory in the command.

You even can use vimdiff on two (or more) remote hosts with this

0

I found this problem quite fascinating and asked myself, if a scripting language could provide the solution: Scripts are, after all, just text files, and can easily be transferred or even typed in.

So I sat down and wrote an ed clone in pure perl as a single standalone script in under 150 lines of code (admittedly, the readability could be better).

It's an early beta, but if you have perl installed on the machine, you could try it out. I Would be interested in the results!

(P.S.: I could not resist to optionally add GNU Readline support to ed. It makes the editing much more fun!)

MC68020
  • 7,981
0

If you really can't edit it somewhere else and transfer the modified file:

step1: you can use cat -n /path/to/the_file : to figure out the line numbers of the section you want to modify. For exemple line 12 to 15.

step2: prepare a replacement file:

cat > /tmp/replacement
enter the replacement lines ... do step 2) again if necessary (mistyped, etc)
ctrl-d
# verify it afterwards: cat -n -ve /tmp/replacement
# -v : shows weird characters you may have mistakenly edited as: ^x (ex: ^@ = \000 = NUL, ^M = \015 = LF, etc.)
# -e : shows "$" at each line ending

step3: you can then just use bash internal commands to edit that:

line_number=0
while IFS= read -r line; do
    line_number=$(( line_number + 1 ))
    if [ $line_number -lt 12 ] || [ $line_number -gt 15 ]; then
        printf "%s\n" "$line"
    else
        cat /tmp/replacement
    fi
done </path/to/the_file  >/tmp/the_file.new

step4: another cat -n /tmp/the_file.new to ensure it is correct (or repeat the steps 2 and 3 for any missing section

step5: cat /tmp/the_file.new > /path/to/the_file # replace its content with the new version. This keeps all ownership & rights of /path/to/the_file

if you for exemple also need to replace every occurence of "foo" to "bar" in the_file: add a case at right place:

case "$line" in
    *foo*) printf "%s\n" "${line/foo/bar}" ;;
    *) printf "%s\n" "${line}" ;;
esac
0

I earlier said that scripting languages could aid here, and gave as an example my re-implementation of ed in 150 lines of perl. But then I thought that it should be possible to type in an editor with much less.

The idea is the following: write a short script that

  1. loads a file given in the command line into an internal buffer (perl array)
  2. starts a eval-loop, during which you can change the buffer's content using arbitary perl code
  3. write the contents back to the file after pressing Ctrl-D.

A minimal implementation of this would be like this:

use v5.10;
use strict; use warnings; `
our @b = ( $ARGV[0] ); our (@x, @u);
while (<>) { chomp; push @b, $_ }
chomp and eval and print STDERR $@ while <STDIN>;
open F, '>', shift @b or die $!; say F for @b; close F;

You now have the lines of the file in the @b array, and now either edit it with perl commands or better add some functions to this file which will ease editing. For more details see the README and the makeshifted file in my repository.

AdminBee
  • 22,803