rsync、scp “tab” 卡顿问题_服务器tab键反应慢怎么办

avatar
作者
筋斗云
阅读量:1

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

–link-dest|-!(-*)T)
compopt +o nospace

调用 filedir() 函数加 -d 参数输出当前目录下的目录

_filedir -d
return
;;
–rsh|-!(-*)e)
compopt +o nospace

COMPREPLY:候选的补全结果

compgen 内置补全命令,根据不同的参数,生成匹配单词的候选补全列表

-W 参数为指定空格分隔的单词列表

COMPREPLY=( ( c o m p g e n − W ′ r s h s s h ′ − − " (compgen -W 'rsh ssh' -- " (compgenWrshssh"cur") )
return
;;
–compress-level)
compopt +o nospace
COMPREPLY=( ( c o m p g e n − W ′ 1..9 ′ − − " (compgen -W '{1..9}' -- " (compgenW1..9"cur") )
return
;;
esac

$split && return

_expand || return

匹配当前光标下的单词

case $cur in
-*)
COMPREPLY=( ( c o m p g e n − W ′ − − v e r b o s e − − q u i e t − − n o − m o t d − − c h e c k s u m . . . ( 此处省略 ) ′ − − " (compgen -W '--verbose --quiet --no-motd --checksum ...(此处省略) ' -- " (compgenWverbosequietnomotdchecksum...(此处省略)"cur") )
[[ $COMPREPLY == *= ]] || compopt +o nospace
;;
*😗)

获取远程主机下的文件路径

find which remote shell is used

local i shell=ssh
for (( i=1; i < cword; i++ )); do
if [[ " w o r d s [ i ] " = = − @ ( e ∣ − r s h ) ] ] ; t h e n s h e l l = {words[i]}" == -@(e|-rsh) ]]; then shell= words[i]"==@(ersh)]];thenshell={words[i+1]}
break
fi
done
[[ $shell == ssh ]] && _xfunc ssh _scp_remote_files
;;
*)

调用 known_hosts_real() 函数,补全已知的主机名列表

_known_hosts_real -c -a – “$cur”

调用命令补全脚本 ssh 下的 scp_local_files() 函数,补全本地文件列表

_xfunc ssh _scp_local_files
;;
esac
} &&
complete -F _rsync -o nospace rsync

ex: filetype=sh

scp 命令补全脚本基本也一致,其获取目标主机下的文件列表的代码如下

case $cur in
!(*😗)/*|[.~]*) ;; # looks like a path
*😗) _scp_remote_files ; return 0 ;;
esac

此时就有一个解决方案就是注释掉 rsync 和 scp 的获取目标主机下文件列表的代码,这样就不会造成卡顿,rsync 和 scp 的其它命令补全仍然可用。但是这样也有一个缺点就是,在目标主机后使用 tab 就什么都 tab 不出来。
而线上服务器的很多文件路径都是一致的,因此想让在目标主机后 tab 出现的是本地文件路径。
那么下面让我们再来看看补全脚本中补全目标主机下的文件路径与补全本地文件路径的代码。

rsync:
*😗)

获取远程主机下的文件路径

find which remote shell is used

local i shell=ssh
for (( i=1; i < cword; i++ )); do
if [[ " w o r d s [ i ] " = = − @ ( e ∣ − r s h ) ] ] ; t h e n s h e l l = {words[i]}" == -@(e|-rsh) ]]; then shell= words[i]"==@(ersh)]];thenshell={words[i+1]}
break
fi
done
[[ $shell == ssh ]] && _xfunc ssh _scp_remote_files
;;
*)

调用 known_hosts_real() 函数,补全已知的主机名列表

_known_hosts_real -c -a – “$cur”

调用命令补全脚本 ssh 下的 scp_local_files() 函数,补全本地文件列表

_xfunc ssh _scp_local_files
;;

scp:
case $cur in
!(*😗)/*|[.~]*) ;; # looks like a path
*😗) _scp_remote_files ; return 0 ;;
esac

补全远程主机下的文件路径主要是通过调用 ssh 的 scp_remote_files() 函数,而补全本地文件路径则是通过调用 ssh scp_local_files() 函数。

下面先看一下 scp_remote_files 函数:

Complete remote files with ssh. If the first arg is -d, complete on dirs

only. Returns paths escaped with three backslashes.

_scp_remote_files()
{
local IFS=$‘\n’

remove backslash escape from the first colon

将当前光标下的单词中的 “:” 转换为 “:”

cur=${cur/\😕:}

获取目标主机名

local userhost=${cur%%?(\)😗}

获取路径

local path=${cur#*:}

unescape (3 backslashes to 1 for chars we escaped)

path=KaTeX parse error: Can't use function '\(' in math mode at position 19: …ed -e 's/\\\\\\\̲(̲'_scp_path_esc’)/\\1/g’ <<<“$path” )

default to home dir of specified user on remote host

if [[ -z p a t h ] ] ; t h e n p a t h = path ]]; then path= path]];thenpath=(ssh -o ‘Batchmode yes’ $userhost pwd 2>/dev/null)
fi

local files

到远程去补全路径

if [[ $1 == -d ]]; then

escape problematic characters; remove non-dirs

files=$( ssh -o ‘Batchmode yes’ u s e r h o s t   c o m m a n d l s − a F 1 d L " userhost \ command ls -aF1dL " userhost commandlsaF1dL"path*" 2>/dev/null |
sed -e ‘s/’KaTeX parse error: Expected 'EOF', got '&' at position 22: …ath_esc'/\\\\\\&̲/g' -e '/[^\/]/d’ )
else

escape problematic characters; remove executables, aliases, pipes

and sockets; add space at end of file names

files=$( ssh -o ‘Batchmode yes’ u s e r h o s t   c o m m a n d l s − a F 1 d L " userhost \ command ls -aF1dL " userhost commandlsaF1dL"path*" 2>/dev/null |
sed -e ‘s/’KaTeX parse error: Expected 'EOF', got '&' at position 22: …ath_esc'/\\\\\\&̲/g' -e 's/[\*@|…//g’
-e ‘s/[^/]$/& /g’ )
fi
COMPREPLY+=( $files )
}

scp_local_files() 函数如下

This approach is used instead of _filedir to get a space appended

after local file/dir completions, and -o nospace retained for others.

If first arg is -d, complete on directory names only. The next arg is

an optional prefix to add to returned completions.

_scp_local_files()
{
local IFS=$‘\n’

local dirsonly=false
if [[ $1 == -d ]]; then
dirsonly=true
shift
fi

if $dirsonly ; then
COMPREPLY+=( $( command ls -aF1dL KaTeX parse error: Undefined control sequence: \* at position 4: cur\̲*̲ 2>/dev/null | …_scp_path_esc/\\&/g" -e ‘/[^/]$/d’ -e “s/^/$1/”) )
else
COMPREPLY+=( $( command ls -aF1dL KaTeX parse error: Undefined control sequence: \* at position 4: cur\̲*̲ 2>/dev/null | …_scp_path_esc/\\&/g" -e ‘s/[*@|=]KaTeX parse error: Undefined control sequence: \/ at position 16: //g' \ -e 's/[^\̲/̲]/& /g’ -e “s/^/$1/”) )
fi
}

从上述看出,当执行下列命令后,bash-completion 首先会调用 rsync 命令补全脚本进行匹配,然后通过一个判断选择匹配到 “:” 项,调用 scp_remote_file 函数获取目标主机路径。scp_remote_file() 函数中,此时 cur 变量的值为"compute:",那么 path 变量的值为空 ,在通过一个 if 语句判断如果 path 值为空,则到 ssh 到远程目标主机执行 pwd 命令并将结果赋值给 path,然后通过 ssh 远程到目标主机执行 ls -aF1dL “$path*” 命令获取所有以 $path 开头的最小路径。

rsync -av compute:[按 tab键]

scp_local_files() 函数也是一样,不过只是少了 ssh 到远程主机执行对应的补全命令。
因此我们若是想要让在目标主机后按 tab 键补全的是本地文件路径,那么我们就可以调用 scp_local_files 函数进行补全,不过在调用之前,需要将 cur 的值进行一个切割,只保留其后面的路径部分,因此对于 rsync 命令补全脚本,我们可以这么改。

将 /usr/share/bash-completion/completions/rsync 配置文件中 *😗) 选项下的命令更改为

*😗)
cur=${cur#*:}
_xfunc ssh _scp_local_files

# find which remote shell is used

local i shell=ssh

for (( i=1; i < cword; i++ )); do

if [[ “${words[i]}” == -@(e|-rsh) ]]; then

shell=${words[i+1]}

break

fi

done

[[ $shell == ssh ]] && _xfunc ssh _scp_remote_files

;;

同样 scp 命令补全脚本,也只需要做同样的改动。

将 /usr/share/bash-completion/completions/scp 配置文件中的

case $cur in
!(*😗)/*|[.~]*) ;; # looks like a path
*😗) _scp_remote_files ; return ;;
esac

更改为

case KaTeX parse error: Undefined control sequence: \* at position 10: cur in !(\̲*̲:\*)/\*|[.~]\*)…{cur#*:}; _xfunc ssh _scp_local_files ;;
esac

即可

参考链接 :
rsync、scp “tab” 卡顿问题 :
https://mp.weixin.qq.com/s/lkdKADQx2NgeNk5ShZYBDw

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ZYBDw

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-mOUs9sFz-1713157806940)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!