Bash的基本特性之命令行的5个标准补全

在 Linux 系统中,默认情况下 Bash 就提供了下面这几个可以供用户在命令行使用的标准补全:

  • 变量名补全
  • 用户名补全
  • 可执行命令补全
  • 文件名和目录补全
  • 主机名补全

变量名补全

在终端输入 $ 后,敲两次 Tab 键就会列出所有可用的 shell 变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@study ~]# echo $[Tab][Tab]
$_ $COLUMNS $LESSOPEN $PS4
$BASH $COMP_WORDBREAKS $LINENO $PWD
$BASH_ALIASES $DIRSTACK $LINES $RANDOM
$BASH_ARGC $EUID $LOGNAME $SECONDS
$BASH_ARGV $GROUPS $LS_COLORS $SHELL
$BASH_CMDS $HISTCMD $MACHTYPE $SHELLOPTS
$BASH_COMMAND $HISTCONTROL $MAIL $SHLVL
$BASH_LINENO $HISTFILE $MAILCHECK $SSH_CLIENT
$BASHOPTS $HISTFILESIZE $OPTERR $SSH_CONNECTION
$BASHPID $HISTSIZE $OPTIND $SSH_TTY
$BASH_SOURCE $HOME $OSTYPE $TERM
$BASH_SUBSHELL $HOSTNAME $PATH $UID
$BASH_VERSINFO $HOSTTYPE $PIPESTATUS $USER
$BASH_VERSION $ID $PPID $XDG_RUNTIME_DIR
$COBBLER_SERVER $IFS $PS1 $XDG_SESSION_ID
$colors $LANG $PS2
[root@study ~]#

用户名补全

当在波浪符 ~ 后按下两次 Tab 键,Bash 就会自动开始用户名的补全。

1
2
3
4
5
6
7
8
[root@study ~]# cd ~
~adm/ ~games/ ~polkitd/ ~systemd-network/
~bin/ ~halt/ ~postfix/ ~tcpdump/
~chrony/ ~lp/ ~root/ ~tss
~daemon/ ~mail/ ~shutdown/ ~user1/
~dbus/ ~nobody/ ~sshd/
~ftp ~operator/ ~sync/
[root@study ~]#

需要注意的是,这里的用户名补全并不是在用户的家目录 (home) 下获得用户名,与此相反它是从 /etc/passwd 中列出所有可用的用户名。

所以对于一些非登陆用户(没有家目录),使用 cd 命令切换会是失败的。

1
2
3
4
5
[root@study sbin]# cd ~ftp 
-bash: cd: /var/ftp: No such file or directory
[root@study sbin]# grep ftp /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@study sbin]#

可执行命令的路径补全

当你想要执行一个命令的时候,如果这个命令具有可执行权限,那么如果只能找到一个匹配项,按两次 Tab 就会直接自动完成补全。

1
2
3
4
[root@study ~]# ll /usr/bin/systemctl 
-rwxr-xr-x. 1 root root 717688 Apr 11 2018 /usr/bin/systemctl
[root@study ~]# /usr/bin/systemc[Tab][Tab]
[root@study ~]# /usr/bin/systemctl

如果找到多个匹配项,按两次 Tab 就会列出匹配的所有可用命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@study ~]# /usr/bin/system[Tab][Tab]
systemctl systemd-inhibit
systemd-analyze systemd-loginctl
systemd-ask-password systemd-machine-id-setup
systemd-cat systemd-notify
systemd-cgls systemd-nspawn
systemd-cgtop systemd-path
systemd-coredumpctl systemd-run
systemd-delta systemd-stdio-bridge
systemd-detect-virt systemd-sysv-convert
systemd-escape systemd-tmpfiles
systemd-firstboot systemd-tty-ask-password-agent
systemd-hwdb
[root@study ~]#

一般情况下我们不会使用绝对路径来执行命令,而是上来就直接执行命令。为什么能直接执行这个命了呢?在 Bash 中,提供了 PATH 环境变量,在他指定的每个路径下会搜索并尝试补全以我们给出的字符串开头的可执行文件(命令)。

1
[root@study ~]# cat ~/.bash_profile

和当前用户相关的配置文件就是 ~/.bash_profile

1
2
3
4
5
6
7
8
9
10
11
12
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

如果我们想要在命令行补全中添加自己指定的路径下的命令,就可以在原有的基础上以 : 作为分隔符添加自己的路径。

1
2
3
4
5
# User specific environment and startup programs

PATH=$PATH:$HOME/bin:/opt/bin/

export PATH

文件名和目录补全

这是对在命令行的第二个位置和后续位置出现的文件名和目录名的补全。与上面的示例不同,它不检查任何权限,在给出的起始路径下只显示所有可用的文件和目录,并试图补全。

1
2
3
4
5
6
[root@study ~]# ls
dir1 dir2 dir3 file1 file2 file3 hello.sh
[root@study ~]# cat file[Tab][Tab]
file1 file2 file3
[root@study ~]# cat h[Tab][Tab]
[root@study ~]# cat hello.sh

除此之外,如果要显示的文件太多,这可能会让人感到非常懵逼,它将给出警告消息而不是在屏幕上显示所有可用的文件。

1
2
[root@study ~]# ls /etc/[Tab][Tab]
Display all 185 possibilities? (y or n)

主机名补全

如果在 ssh 连接一个远程主机时,想要获得要连接的主机名,请在 @ 后按两次 Tab 键,如下所示:

1
2
3
4
5
[root@study ~]# ssh root@[Tab][Tab]
@::1 @localhost6
@localhost @localhost6.localdomain6
@localhost4 @localhost.localdomain
@localhost4.localdomain4

在任何可以为主机名提供 @ 的命令中,都可以使用这个主机名补全功能。例如,可以将其与 scp 命令一起使用。

1
2
3
4
5
[root@study ~]# scp file1 root@[Tab][Tab]
@::1 @localhost6
@localhost @localhost6.localdomain6
@localhost4 @localhost.localdomain
@localhost4.localdomain4

echo 也是可以的:

1
2
3
4
5
[root@study ~]# echo @[Tab][Tab]
@::1 @localhost6
@localhost @localhost6.localdomain6
@localhost4 @localhost.localdomain
@localhost4.localdomain4

参考:https://www.thegeekstuff.com/2013/11/bash-standard-completion/

有钱任性,请我吃包辣条
0%