In bash, environmental variables not tab-expanding correctly - bash

In bash, environmental variables will tab-expand correctly when placed after an echo command, for example:
echo $HOME
But after cd or cat, bash places a \ before the $ sign, like so:
cd \$HOME
If I use a variable as the second argument to a command, it won't expand at all:
cp somefile $HOM
What mysterious option do I have in my .bashrc or .inputrc file that is causing me such distress?

What you're describing is a "feature" introduced in bash 4.2. So you don't have any mysterious option causing you distress, but just "intended" behaviour.
I find this very annoying since I preferred it the way it used to be and haven't found any configuration options yet to get the earlier behaviour back. Playing with complete options as suggested by other answers didn't get me anywhere.

Try complete -r cd to remove the special programmatic completion function that many Linux distributions install for the cd command. The function adds searching a list of of directories specified in the CDPATH variable to tab completions for cd, but at the expense of breaking the default completion behavior.
See http://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion for more gory details.

For the second instance, you can press ESC before tab to solve it.
I don't know the solution to your problem, but you could look in /etc/bash_completion or the files under /etc/bash_completion.d to determine what commands use autocompletion and how.
help complete
Might also be helpful.

The Bash Reference Manual has more information than you might want on expansion errata.
Section 8.7 looks like it would be the place to start. It give information on the 'complete' function, among other things.

Check the answer for
https://superuser.com/questions/434139/urxvt-tab-expand-environment-variables by Dmitry Alexandrov:
This is about direxpand option. $ shopt -s direxpand and $FOO_PATH/ will be expanded by TAB.

I'm answering 4-year-old question! Fantastic!
This is a bash bug/feature which was unintentionally introduced in v4.2, and was unnoticed for a long period of time. This was pointed out by geirha in this tread. Confirmed as unintended feature here
I came across this problem when running Ubuntu at home. At work I have bash-3.00, so I've spent some time browsing around to see what's going on. I wonder if I can 'downgrade'....

Related

Bash: ls command displaying recursively, though -R not specified

I'm having a frustrating, but seemingly simple problem. I was recently pushing some files to github and now ls has started listing directory contents recursively when I use the basic command ls. Though, it only appears to do so in my Google Drive folder. It functions normally when used in directories outside of Google Drive. I'm not sure if it is connected to something I was doing with git or completely unrelated. I had been working on a github project in my Google Drive when I noticed the issue.
The output of type ls in the Google Drive directory and outside of it is:
ls is hashed (/bin/ls)
Does anyone have any input on how I can get ls to function 'normally' again? I'm not sure how I could've changed its function but it appears I must have. Let me know if there is additional information that would help in understanding the problem.
Thank you in advance
Your ls might be aliased (perhaps in your ~/.bashrc; look inside file that with your editor) by your interactive shell (or it might become a bash function). Check with type ls (using the type builtin).
Use \ls or /bin/ls to get the real ls program.
If your shell is bash, be sure to read the chapter on bash startup files.
Try also using stat(1) and/or some other shell (e.g. zsh, sash, ...).
SOLVED:
I'm not sure why this was occurring, but the issue seems to be related to having updated a Shiny app through rsconnect() in R. I closed RStudio and now the ls command is working properly again in all directories. I have no idea why this would occur and didn't think that would be related at all. Thanks for the troubleshooting help!

nullglob disables pathname tab-completion

I have found that shopt -s nullglob apparently disables tab-completion for files and directories, and shopt -u nullglob restores it. Why does tab-completion for directories apparently rely on nullglob being unset?
I am using Bash 4.2.37(1)-release on Debian 7.
This is apparently a known issue with bash-completion and is listed as an objective to be fixed in the 3.0 version.
But apparently it has been that way since at least 2012.
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666933 for reference.
Edit: At least 2011: http://thread.gmane.org/gmane.comp.shells.bash.completion.devel/3652
I do not at all understand how nullglob causes the problem listed in that email though.
Edit: I now understand what is happening. The problem is that glob expansion is dumb. It sees the entire "word" $2[$j]=\${!ref}\${COMP_WORDS[i]} as a single glob and tries to expand it. Normally that fails and it gets left alone but will nullglob on that entire argument simply vanishes (thus causing the problem).
Quick testing indicates that replacing this:
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
with either:
eval $2\[$j\]=\${!ref}\${COMP_WORDS\[i\]}
or:
eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"
seems to fix the problem. I can't vouch for either of those being a fully correct fix though.
Update: This is fixed in the debian bash-completion git repository already (in a way I hadn't thought of but which is clearly better).
This commit fixes it. There are other globbing related fixes too.
Grabbing the __reassemble_comp_words_by_ref from git head and sourcing that on top of the current one appears to fix the problem as a temporary workaround/solution.

How to configure bash completion to expand partial path like in emacs "minibuffer-complete"?

I would like to configure my bash shell to expand partially entered tree structure like it does emacs "minibuffer-complete" command.
Imagine I have two folders, foo1 and foo2. foo1 contains a subfolder sub1, and foo2 contains subfolder wow. So I have:
foo1/sub1/
foo2/wow/
Now when opening a file in emacs if I type
f/w
and press TAB it will automatically expand it to "foo1/wow/".
I would like to have a similar functionality in bash. Any ideas?
Whilst I don't know how to do this in bash, or even if it's possible, I know that if you change your shell to zsh, it can be done.
It's not enabled by default, and I'm not sure how to enable it either, but I use the zsh grml config, which enables the kind of expansion you're talking about.
Zsh, especially combined with said config, also has many other helpful features.
If you're not willing to change shell, then this isn't a helpful answer I'm afraid.
you can have it the other way around, using emacs M-x shell command. It open a Shell buffer with an autocompletion like in the minibuffer
Disclosure: I am the author of the project
I have written the completion functions necessary to enable such completion in bash: https://github.com/sio/bash-complete-partial-path
Hope you'll find this project useful

Mysterious phantom rm -i alias

I'm using zsh on Mac OS 10.6.8.
So, all of a sudden one of my machines asks me for confirmation every time I rm.
Frankly, I hate this with an abiding passion. I've never had a problem with rm, and I don't need to debate the potentialities.
First thing I did was which rm, which reports rm: aliased to rm -i.
Now, I've hunted high and low for this alias. zshrc, .config (which I don't have), the default zshrc files: everywhere I can think of. No mention of aliasing rm anywhere.
Is there a simple way to determine where this alias is being configured? Or to list all locations where zsh might be looking for config lines?
Nope, there's no way to know which startup file an alias has been configured from, sort of searching them yourself.
The Z-shell startup files can be found here.
A comment for the question suggests /etc/profile; this is incorrect (unless you're sourcing it yourself), as /etc/profile is a Bourne-type shell startup file.
If you can't find the place it's sourced, you could unset the alias [bottom paragraph] in ~/.zshrc: unset rm. That should work provided it's done after the alias is set.

Emacs ido-style shell

Is there a command line shell or shell customization that supports emacs-style ido find file? In emacs, I can navigate to a directory extremely quickly using C-x C-f and (ido-mode t).
Ideally, I'm looking for a solution that can be used outside of emacs. Though I'd be open for a way to quickly change directories within an eshell buffer.
Since I also wanted something like this, I tried to implement it as a bash completion
function. Obviously it means. you have to use bash.
It is only lightly tested, so please feel free to try and report bugs /comments.
http://pgas.freeshell.org/shell/bash-ido
Try the Z-shell. It has much better completion than bash. I must admit I haven't used it for a while though and stuck with bash because it's always available.
Bash has an environment variable called CDPATH which can contain a list of directories to search when using the cd command. Also, check out the "Programmable Completion" and "READLINE" sections of the Bash manual. You should be able to cobble together something that works for you.
The best I've been able to come up with so far is autojump. Still looking for a solution closer to ido, but autojump is a great little app.
I know that some terminal emulator support extension, for instance rxvt-unicode can be extended with Perl scripts. I'm not sure since i never wrote an extension myself, but maybe what you want is doable this way.
If you want to have a look at some Perl scripts for urxvt there are some examples in /usr/lib/urxvt/perl with the default urxvt install on Debian.
If you want ido completion in eshell or similar, it might be best to write a function that uses ido to read a directory, then inserts the command to cd to that directory into the shell buffer. I don't use eshell myself, so I couldn't comment on how to actually write this function, but it's an idea.
fzf, the command-line fuzzy finder, adds fuzzy completion for bash and zsh.
According to the developer:
It's an interactive Unix filter for command-line that can be used with
any list; files, command history, processes, hostnames, bookmarks, git
commits, etc.
This is a portable solution (works on Linux, Mac, Windows), which has no dependencies.

Resources