有时我需要快速将文件从远程服务器复制到本地计算机。这是我当前的工作流程:
- 我通过 SSH 进入我的远程服务器,找到该文件并复制其完整路径。
- 我打开新的终端选项卡并输入:
sftp user@hostname:/path/to/file
(其中 /path/to/file 是我之前复制的路径)
这并不是一件很麻烦的事情,但是如果我可以跳过步骤 1 并在键入 sftp 命令时直接使用制表符补全找到文件的路径,那就太好了。
举例来说,我可以开始输入sftp user@hostname:/
pressTAB并获取 / 中的文件夹列表。然后我可以继续输入ho
press TAB,它会自动完成为home
,等等。等等。
我不确定是否存在这样的功能,否则,理论上是否可以编写如所述自定义制表符补全脚本?有什么建议可以指导您从哪里开始吗?
答案1
感谢 shellholic 的回答,我能够让它(在某种程度上)适用于 sftp。首先,创建/etc/bash_completion.d/sftp
具有以下内容的文件:
# custom sftp(1) based on scp
# see http://askubuntu.com/questions/14645/is-it-possible-to-get-tab-completion-with-sftp
#
_sftp()
{
local configfile cur userhost path prefix
COMPREPLY=()
cur=`_get_cword ":"`
_expand || return 0
if [[ "$cur" == *:* ]]; then
local IFS=$'\t\n'
# remove backslash escape from :
cur=${cur/\\:/:}
userhost=${cur%%?(\\):*}
path=${cur#*:}
# unescape spaces
path=${path//\\\\\\\\ / }
if [ -z "$path" ]; then
# default to home dir of specified user on remote host
path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
fi
# escape spaces; remove executables, aliases, pipes and sockets;
# add space at end of file names
COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \
command ls -aF1d "$path*" 2>/dev/null | \
sed -e "s/[][(){}<>\",:;^&\!$=?\`|\\ ']/\\\\\\\\\\\\&/g" \
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
return 0
fi
if [[ "$cur" = -F* ]]; then
cur=${cur#-F}
prefix=-F
else
# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
set -- "${COMP_WORDS[@]}"
while [ $# -gt 0 ]; do
if [ "${1:0:2}" = -F ]; then
if [ ${#1} -gt 2 ]; then
configfile="$(dequote "${1:2}")"
else
shift
[ "$1" ] && configfile="$(dequote "$1")"
fi
break
fi
shift
done
[[ "$cur" == */* ]] || _known_hosts_real -c -a -F "$configfile" "$cur"
fi
# This approach is used instead of _filedir to get a space appended
# after local file/dir completions, and $nospace retained for others.
local IFS=$'\t\n'
COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | sed \
-e "s/[][(){}<>\",:;^&\!$=?\`|\\ ']/\\\\&/g" \
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/$prefix/") )
return 0
}
complete -o nospace -F _sftp sftp
然后您需要在 bash 中执行. /etc/bash_completion.d/sftp
以加载脚本。
我实际上所做的只是复制/粘贴 scp 完成脚本,/etc/bash_completion.d/ssh
并用 sftp 替换 scp 出现。
答案2
另一种选择:改用lftp
,它具有出色的内置制表符补全功能(但那是在启动它时,而不是在 shell 中。)它可以谈论 sftp 和许多其他协议。
答案3
不要使用sftp
,使用scp
就可以了。您将需要一个 ssh 密钥。
答案4
我听说有一个项目叫使用 readline将允许标准 OpenSSH 命令行程序安全FTP使用 Tab 补全。我无法验证它是否有效,但多年来我一直想要同样的功能。
有关 with-readline 和 sftp 的信息: http://www.greenend.org.uk/rjk/2005/withreadline.html
with-readline 链接: http://www.greenend.org.uk/rjk/2005/with-readline-0.1.tar.bz2
请让我知道它对你的作用如何。