参考:
实测,代码可运行.
1. 如果遇到 syntax error near unexpected token 问题,基本是由于 windows 环境下编写的 shell 脚本上传到 UNIX 中包含了 ^M 引起的。
使用替换掉 sh 脚本中的 ^M 字符,也可以使用 vi -b your_file 编辑文件。
如果 scp.conf 报 syntax error near unexpected token 问题,则 vi -b scp.conf 编辑此配置文件,替换掉其中的特殊字符。
2. 如果遇到 source: not found 的异常,查看。
原作者的脚本在 copy dir 的时候,会将整个 dir 目录拷贝至 target 中,这跟 scp 命令本身有关。
scp -r ./code/oaf/* :P
但是此处不能用 sh multi_scp.sh ./scp.conf ./code/oaf/* $JAVA_TOP, 会抛出异常。
所以我针对想仅拷贝目录下的文件及文件夹做了一点改动。
把 multi_scp.sh 中的
- /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file" "$scp_target"
改为了
- if [ -d "$scp_file" ]
- then
- for f in ` ls "$scp_file"`
- do
- /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file/$f" "$scp_target"
- done
- else
- #scp file or dir
- /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file" "$scp_target"
- fi
鉴于此种方式需要使用 linux 的 expect 模块,我又写了一个简陋的 scp,此种方式需要在每次执行 scp 的时候交互式的输入 scp 的密码,但是特别繁琐,所以就想到了加入 ssh 信任免密码登录。
Step 1.
Step 2. $ sh (下载)
- #!/bin/bash
- ssh_hosts=("192.168.233.136" "192.168.233.137")
- default_ssh_user="huanghongbo"
- default_ssh_password="huanghongbo"
- default_ssh_port="22"
- port=$default_ssh_port
- scp_file=./code/oaf/
- target=$JAVA_TOP
- scpuser=$default_ssh_user
- for((i=0;i<${#ssh_hosts[@]};i++))
- do
- #remote ssh host
- scphost=${ssh_hosts[$i]}
- echo $i node ,host is $scphost
- #echo "["`date +"%F %T"`"] (scp -r $scp_file $ssh_user@$ssh_host:$ssh_port:$scp_target) start"
- echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target ) start"
- #scp -q -r -P $port $scp_file/* $scpuser@$scphost:$target
- #-q 不显示传输进度
- scp -r -P $port $scp_file/* $scpuser@$scphost:$target
- if [ "$?" -eq "0" ]
- then
- success_hosts="$success_hosts,$scphost"
- else
- fail_hosts="$fail_hosts,$scphost"
- fi
- echo "["`date +"%F %T"`"] (scp -r -P $port $scp_file $scpuser@$scphost:$target ) end"
- done
- echo "success_hosts=[$success_hosts]"
- echo "fail_hosts=[$fail_hosts]"
PS:
1. 示例中的 target 都是使用的环境变量 $JAVA_TOP, 如果 remote 环境和 local 环境的 $JAVA_TOP 环境变量不一致,则会导致传输到错误的路径或者 scp:***:No such file or directory。
在 scp 中如何获取 remote 环境的环境变量,我暂时还没找到方法。
看到的一种比较合理的解释是
How is it supposed to know what the remote variables values are? scp/rcp DO NOT execute a .profile or any login script. They establish a connection to the remote server only.
2.Expect 在这个程序里就是用来帮助自动输入 scp 的密码, Expect 主要用于把需要人工交互的程序变为程序自动化完成,这个对于运维批量部署系统, 批量无人值守安装,批量执行命令,批量上传下载
现代的 Shell 对程序提供了最小限度的控制 (开始,停止,等等),而把交互的特性留给了用户。 这意味着有些程序,你不能非交互的运行,比如说 passwd。 有一些程序可以非交互的运行,但在很大程度上丧失了灵活性,比如说 fsck。这表明 Unix 的工具构造逻辑开始出现问题。Expect 恰恰填补了其中的一些裂痕,解决了在 Unix 环境中长期存在着的一些问题。
来源: