6

TL;DR : default shell man page says there's vi editing mode, but set -o vi doesn't actually enable it

In many shells, including dash the POSIX standard dictates that set -o vi will enable vi editing mode, in which user of interactive shell can navigate line using vi-style of shortcuts. In dash ( Ubuntu's default shell symlinked to /bin/sh ) this doesn't work, even though man page specifies that this feature is available.

Example :

$ dash
$ set -o vi
$ hello wolrd^[I

What was supposed to happen there is that with Esc , Shift + i shortcut the cursor should have jumped to the beginning of the line. As you can see, I get a control character as output instead. I've asked a few users to test this in AskUbuntu Chat, and they confirmed the same behavior.

Note, that this is not related to terminal emulator - I tested it in 3 different ones: xterm, gnome-terminal, and terminator. I've tested this with other shells, bash, mksh and ksh93 - all work properly as expected, so this is dash-only issue.

Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497

1 Answers1

2

I was curious about this so I downloaded a source code tarball from the upstream DASH downloads and extracted the source files. I checked for a README file which should provide information on the program and its build options, but there wasn’t any, so I ran ./configure --help and its output includes:

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-libedit          Compile with libedit support

So, it looks like the libedit library is used to provide line editing capabilities but this is not the default when building the source. I also found this response to a mailing list message on set -o vi not working:

I think this requires dash to be built with libedit support to work.

I checked what libraries were linked to the dash executable on my Ubuntu server and noted libedit wasn’t included:

$ ldd /bin/dash
        linux-vdso.so.1 =>  (0x00007fffcfbd6000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f013a0b7000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f013a475000)

I imagine that when the Debian package maintainers are building the dash package, they omit this optional configuration as they would not want sh to have external dependencies on other libraries. They could probably link the library statically but the main reason for using dash as sh is to keep the shell as small and fast as possible so that the start-up scripts run quickly.

Edit: I just searched for “libedit dash” and the top result was a very similar question on this site which was well answered by muru.

Building Dash with line editing support

For those who might be interested, these are are steps required to build from source.

  1. Download the most recent source tarball:

    wget http://gondor.apana.org.au/~herbert/dash/files/dash-0.5.9.tar.gz
    wget http://gondor.apana.org.au/~herbert/dash/files/dash-0.5.9.tar.gz.sha256sum
    
  2. Verify the authenticity of the tarball:

    sha256sum -c <( awk '/dash/{ print $1 "  "  $3}' dash-0.5.9.tar.gz.sha256sum )
    gpg --verify --auto-key-retrieve dash-0.5.9.tar.gz.sha256sum
    
  3. Extract the source files and change into the source directory:

    tar -xf dash-0.5.9.tar.gz
    cd dash-0.5.9
    
  4. Run ./configure --with-libedit to create the Make files. However, this will fail quietly unless the development version of the libedit library is installed. It would be better if the configure script complained more verbosely as it wasn’t obvious that it was failing to find the required files.

    sudo apt-get install libedit-dev
    ./configure --with-libedit
    
  5. Build the program and (optionally) install it into /usr/local/bin:

    make
    sudo make install
    
  • That same question that was answered by muru was asked by me :) – Sergiy Kolodyazhnyy Sep 19 '16 at 11:07
  • That's not exactly the case of bad memory here. I discovered vi editing mode only a few days ago. Since i use vim a lot now, i had idea that this might be used in dash. Back when i asked that question vi and emacs editing modes didn't concern me, so i didn't notice that part of muru's answer. It's a bit disappointing because POSIX standard requires having vi editing mode, so Debian and Ubuntu devs basically don't match up to POSIX when they compile dash without libedit. Sad but i guess we just have to deal with it – Sergiy Kolodyazhnyy Sep 19 '16 at 11:22
  • @Serg Ah. That makes sense. Despite being a Vim user,I still haven't made up my mind whether I prefer vi or emac mode for line editing. FWIW, I noticed that tcsh had nicer support for vi-mode than Bash's Readline. BTW, I've built dash with libedit and the line editing works fine. I still couldn't see myself using it as my regular shell since it lacks tab completion as it isn't specified by POSIX. – Anthony Geoghegan Sep 19 '16 at 11:36
  • I don't intend to regularly use dash as interactive shell as well, but it is nice to have it handy when I mess up my rc files for either bash or mksh ( which is what I regularly use ). Yeah, Tab completion is also something that would be nice to have, but I could leave without it. Inability to edit commands is what drives me up the wall – Sergiy Kolodyazhnyy Sep 19 '16 at 11:49
  • @Serg It took me a lot longer than I intended to build the source code so I've edited my answer to include those steps. Since dash is so small, the build is very fast - as long as you have the necessary library development files. – Anthony Geoghegan Sep 19 '16 at 11:56