使用*通配符时scp自定义函数行为异常,如何让tocomp2匹配所有文件?
解决bash中scp函数本地文件通配符批量传输问题
问题背景
在Ubuntu 22.04的bash环境中,我在/home/.bashrc中定义了两个用于和服务器comp2(IP:192.168.1.2)传输文件的scp函数:
tocomp2() { scp "$1" comp2@192.168.1.2:"$2" } fromcomp2() { scp comp2@192.168.1.2:"$1" "$2" }
本地工作目录存在foo1、foo2、foo3三个文件,comp2服务器主目录存在bar、bar2、bar3三个文件。使用通配符时出现如下异常:
- 执行
tocomp2 foo* /home/仅传输foo1一个文件 - 执行
tocomp2 foo\* /home/提示找不到文件 - 执行
fromcomp2 bar* ./或fromcomp2 bar\* ./可正常传输全部三个bar文件
问题原因
执行tocomp2 foo* /home/时,bash会先在本地将foo*展开为foo1 foo2 foo3,此时函数实际接收的参数是foo1、foo2、foo3、/home/。但原函数仅处理$1(第一个参数foo1)和$2(第二个参数foo2),/home/被当成了第三个参数未被处理,因此scp只传输了foo1。
而fromcomp2的bar*是作为远程路径的一部分传入,scp会将该通配符发送到服务器端,由服务器的shell完成展开,因此能匹配到所有bar文件。
解决方案
修改tocomp2函数,使其支持接收多个本地文件参数,将除最后一个参数外的所有参数作为本地文件,最后一个参数作为远程目标路径:
tocomp2() { scp "${@:1:$#-1}" comp2@192.168.1.2:"${!#}" }
说明
${@:1:$#-1}:表示取从第1个到倒数第2个的所有参数,即所有本地文件${!#}:表示取最后一个参数,即远程目标路径
修改后,执行tocomp2 foo* /home/,bash展开foo*得到的所有foo文件都会被作为本地文件参数传入,scp会一次性将它们传输到服务器的/home/目录下。
内容的提问来源于stack exchange,提问作者Alex Krohn
相关产品推荐
相关产品推荐

