0

I use Windows 10 home (build 16299.248) and I'm SSHing into a remote Ubuntu 16.04 machine with various SSH clients (like Putty/MobaXterm).

I copy-paste the following code from my personal GitHub account into an SSH session:

cat <<-EOF >> "$HOME"/.bashrc
    export s_a="/etc/nginx/sites-available"
    export s_e="/etc/nginx/sites-enabled"
    export drt="/var/www/html"
    source "$HOME"/"$repo"/software_internal.sh
EOF

I copy it directly from my GitHub account here (non-raw version) although the following problem happens even if I copy from GitHub raw version.

My problem

The result in the remote Bash is this:

> .export s_a="/etc/nginx/sites-available"
> .export s_e="/etc/nginx/sites-enabled"
> .export drt="/var/www/html"
> .source "$HOME"/"$repo"/software_internal.sh
> EOF

Note the single dot in the start of almost each line.

Something is translating tabulations into single dots.

Facts

  • The problem I just described happens with various types of SSH clients.

  • People were also able to replicate the problem in Linux systems (Debian, Ubuntu), moreover, if I use Windows 10 Subsystem for Linux (WSL) I don't have the dots (whether from Powershell or CMD). I also don't use Pasteboard / clipboard managers of any kind in Windows 10.

  • There's also no evidence that GitHub is using any nonconventional tab character.

  • It happens when I copy either from Mozilla Firefox or Google Chrome.

  • I didn't change anything in the DigitalOcean Ubuntu Bash after installing it (after creating my "droplet" in the DigitalOcean terminology).

This seems to be a bug in GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu). I was able to replicate the bug In Debian stable 9.3 with Bash 5.2 as well. Yet this problem dosen't happen in Arch, so it's likely to be unique to Debian distributions.

Further information

The problem happens not only in DigitalOcean but in Linode as well - a Linode engineer was able to reproduce this in Ubuntu 14.04, 16.04, and 17.04.

It is possible that DigitalOcean and Linode customize Ubuntu the same way and the bug is not in Bash but still unique to DigitalOcean and Linode.

Summary

The above problem is extremely unlikely to come from either Windows 10, SSH clients, GitHub GUI, or web browsers; It is likely to come either from Debian repositories, Bash in 4.3 / 5.2 / other, or the combination of Debian-Bash.

My question

What is the right way to cope with this problem? I could of course delete the heredocument tabs, but it's definitely something I don't want. The tabs help me to better organize the heredocument.

Arcticooling
  • 1
  • 3
  • 7
  • 22

1 Answers1

4

Bash is doing filename completion inside the heredoc. Your directory has no non-hidden files (files that don't start with '.'), so the longest substring of characters that match the beginning of all filenames in the directory is '.', and that's what is supplied and getting left in your input.

The same version of Bash does exhibit this behavior everywhere I've tried it, so it is clearly not limited to a specific VPS provider. I have been unable to make this stop without disabling completion entirely (so I can't supply a "Here's what Linode needs to do to fix the distro image"), but there are quite a few work-arounds for your specific usage:

  1. The easiest fix, without changing anything in Bash itself is to create a non-hidden file in the directory ($HOME), before the heredoc starts. That will cause the filename completion to match 0 characters. You could do this with say touch "$HOME"/myFile.

  2. Launch a shell with readline disabled and do your thing there. bash --noediting

  3. Toggle completion off before the heredoc: bind 'set disable-completion on'

Arcticooling
  • 1
  • 3
  • 7
  • 22
Carl Cravens
  • 388
  • 1
  • 5
  • I wanted to clarify... this seems to be unrelated to anything the VPS providers are doing. Once I understood the parameters, I reproduced this on my local workstation (both Debian 9 in VirtualBox, and bash on MacOS). So this is very much a bash issue and not a distro or provider issue. You just have to have a moderately narrow set of conditions to have it work exactly this way, and it happens that a newly-installed user's home directory meets those conditions. – Carl Cravens Mar 01 '18 at 20:12
  • Carl, do you agree to edit and explain `why` Bash does that replacement? I'm not sure I understand the `why` or shall I say `how`. – Arcticooling Mar 02 '18 at 05:43
  • I understand that because there are no non-hidden files in the dir, Bash tries to "adjust" my heredoc lines to be "hidden as well" but why does it happen? I miss why would Bash behave this way. – Arcticooling Mar 02 '18 at 05:53
  • I suggested edit. – Arcticooling Mar 02 '18 at 08:21
  • Nice find! @user9303970, `bash` isn’t trying to adjust your heredoc, it’s just doing tab completion as you’d expect on the command-line. It gets even worse once a (single) file does exist in the directory: all your tabs get replaced by the file name... Try `cd $(mktemp -d); touch .bashrc`, then paste your heredoc command. You’ll see `.bashrc` at the start of every heredoc line! – Stephen Kitt Mar 02 '18 at 08:22
  • @StephenKitt, yes. I now understand what's happened there but I must say, I think it's a sersious UX problem when a user that pastes an heredouc inside a dir with `only hidden files but no non-hidden files` would have all leading tabs turn to single dots without any hint. It is extremely elusive and confusing IMHO; Even a small notification could have saved so much hours. – Arcticooling Mar 02 '18 at 08:44
  • @user9303970 I agree it’s a bad UX problem. I very much doubt it’s intentional; probably unwanted interaction between tab-completion (which is expected in interactive mode) and heredocs (which I imagine most people don’t use in interactive mode, at least not with leading tabs). – Stephen Kitt Mar 02 '18 at 08:55
  • I agree, it is really confusing. I'm not entirely sure why bash continues doing completion inside a heredoc, other than you're still "on the command line" and bash developers have never seen a reason to disable completion at that stage. – Carl Cravens Mar 02 '18 at 13:26
  • The rule of thumb is not to use tabs and treat them as reserved characters, especially when they can mess out the output. You're pasting tabs into the terminal and triggering bash-completion that way. – Gothrek Mar 02 '18 at 18:01