You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SSH与Expect脚本实现远程PC目录创建及文件复制?

解决远程目录创建失败与文件复制问题

从你的错误信息和脚本来看,有两个核心问题导致mkdir命令执行失败,进而影响后续的文件复制操作:

1. mkdir无法递归创建父目录

错误提示bash: mkdir /home/marpic/muonic_data/Data_Q2/2018-03-07: Aucun fichier ou dossier de ce type(法语:无此文件或目录),说明目标路径的上层父目录(比如Data_Q2)可能不存在。默认的mkdir命令只能创建最后一级目录,如果路径中的任何上层目录不存在,就会直接报错。

解决方法:给mkdir添加-p参数,它会自动递归创建所有不存在的父目录:

mkdir -p /home/marpic/muonic_data/Data_Q2/2018-03-07

2. Tcl脚本中变量未正确展开

你修改后的脚本里用单引号包裹了ssh命令:

spawn ssh marpic@192.168.110.90 'mkdir $path/$dir'

在Tcl语法中,单引号不会解析内部的变量(比如$path和$dir),这会导致远程主机的bash收到的命令就是mkdir $path/$dir——而bash环境中并没有定义$path变量,最终执行的命令完全不符合预期。

修正脚本的两种可行方式:

方式一:用双引号包裹ssh命令,让Tcl解析变量

把单引号换成双引号,这样Tcl会先将$path和$dir替换为实际值,再把完整命令传给远程主机:

spawn ssh marpic@192.168.110.90 "mkdir -p $path/$dir"

如果你的$myDest变量格式是user@host:/remote/path,可以先提取出远程路径部分,避免硬编码:

# 从$myDest中剥离出远程路径(去掉user@host:前缀)
regexp {.*:(.*)} $myDest -> remote_base_path
spawn ssh marpic@192.168.110.90 "mkdir -p $remote_base_path/$dir"

方式二:直接写完整路径,避免变量混淆

如果$dir是日期类目录(比如2018-03-07),可以直接写死远程路径前缀,让命令更清晰:

spawn ssh marpic@192.168.110.90 "mkdir -p /home/marpic/muonic_data/Data_Q2/$dir"

完整修正后的脚本示例

foreach file $FILES dir $DIRECTORIES {
 set timeout -1;
 puts "\nFichier : $file \n"
 puts "Repertoire : $dir \n"
 # 递归创建远程目标目录
 spawn ssh marpic@192.168.110.90 "mkdir -p /home/marpic/muonic_data/Data_Q2/$dir"
 expect -re "(.*)assword: " {sleep 1; send -- "$pass\r" }
 expect eof
 # 复制文件到已创建的远程目录
 spawn scp -p -r "$mySource/$file" "$myDest/$dir"
 expect -re "(.*)assword: " {sleep 1; send -- "$pass\r" }
 expect -timeout 3600 eof
}

额外优化建议

  • 为了避免每次ssh/scp都输入密码,建议配置SSH密钥登录,这样脚本无需处理密码输入,运行更稳定也更安全。
  • 确保$FILES和$DIRECTORIES两个列表的长度一致,避免循环时出现文件与目录不匹配的情况。

内容的提问来源于stack exchange,提问作者lL. Bob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:50:04