Typing ssh-copy-id -i ~/.ssh/
, then Tab causes filename expansion, which lists all files in ~/.ssh
.
Typing ssh-copy-id
without the -i
flag, then Spacebar, Tab doesn't cause file expansion.
Typing ssh-copy-id -x
, Spacebard, Tab(note that -x
is an invalid flag) also does not lead to file expansion.
How does Bash "know" to do file expansion after typing -i
? Does the program ssh-copy-id
have to be programmed in a way to let Bash know to do it? I read this page and others on filename expansion but could not find an answer for my question:
https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
Bash version:
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
Best Answer
Tab-completion is different from filename expansion.
Tab-completion is a native feature of Bash GNU Readline for interactive Bash sessions. For example, it completes variables (try
echo $SH<TAB>
) and also commands arguments with file names.Additionally, if
bash-completion
package is installed, the completion becomes more intelligent for the commands comprised in in/usr/share/bash-completion/completions
, one of which isssh-copy-id
. Since the-i
flag forssh-copy-id
requires a file, it tab-completes files. Without-i
, there does not make sense to supply a file, so no completion is performed.Again, that is only true for commands in the
completions
directory. If you have afoobar
command that does not accept a file as an argument, Bash will still complete with files becausebash-completion
has no idea offoobar
.On the other hand, filename expansion is a POSIX shell behavior. It occurs regardless of whether the shell is interactive or not. Example:
ssh-copy-id -x *
causes*
to expand to all files in the current directory, the command wanting them or not.