Иногда мне нужно быстро скопировать файл с удаленного сервера на мой локальный компьютер. Вот мой текущий рабочий процесс:
sftp user@hostname:/path/to/file
(где / path / to / file - путь, который я ранее скопировал)
Это не такая боль, но было бы здорово, если бы я мог пропустить шаг 1 и найти путь к файлу, используя завершение табуляции непосредственно при вводе команды sftp.
Чтобы проиллюстрировать это, я могу начать печатать sftp user@hostname:/
, нажав TAB kbd> и получить список папок в /. Затем я мог бы продолжить печатать ho
, нажать TAB kbd>, и он автоматически завершится до home
и т. Д. И т. Д.
Я не уверен, существует ли такая функция, и в противном случае, теоретически возможно ли написать собственный скрипт завершения вкладки, как описано? Есть указания на то, с чего начать?
Благодаря ответу 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= Затем в bash вам нужно выполнить . /etc/bash_completion.d/sftp
, чтобы загрузить скрипт.
Все, что я действительно сделал, это скопировал / вставил скрипт завершения scp из /etc/bash_completion.d/ssh
и заменил вхождения scp на sftp.
\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= Затем в bash вам нужно выполнить . /etc/bash_completion.d/sftp
, чтобы загрузить скрипт.
Все, что я действительно сделал, это скопировал / вставил скрипт завершения scp из /etc/bash_completion.d/ssh
и заменил вхождения scp на sftp.
\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
и заменил вхождения scp на sftp.
Другая альтернатива: используйте вместо этого lftp
, который имеет превосходное встроенное завершение табуляции (но это будет после того, как вы запустите его, а не в оболочке). Он может говорить по sftp и многим другим протоколам.
Не используйте sftp
, используйте scp
, и это работает. Вам понадобится ключ ssh.
Я слышал, что программа под названием with-readline позволит стандартной программе командной строки OpenSSH sftp использовать завершение табуляции. Я не могу убедиться, что это работает, но я давно хотел получить ту же функциональность.
информация о with-readline и sftp: http://www.greenend.org.uk/rjk/2005/withreadline.html
с ссылкой readline: http://www.greenend.org.uk/rjk/2005/with-readline-0.1.tar.bz2
Дайте мне знать, как это работает для вас.