Bash 脚本:使用 Expect 将文件发送到 SFTP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24687754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:55:33  来源:igfitidea点击:

Bash Script: Send files to SFTP using Expect

bashshellunixsftpexpect

提问by Sql_Learner

I have to send few gzipped files from local server to SFTP server.

我必须将一些 gzip 压缩文件从本地服务器发送到 SFTP 服务器。

My Server Info

我的服务器信息

Distributor ID: Ubuntu Description: Ubuntu 12.04.4 LTS Release: 12.04 Codename: precise

发行商 ID:Ubuntu 描述:Ubuntu 12.04.4 LTS 版本:12.04 代号:精确

Created a bash script and could able to send files to sftp, but i want to send email if transfer is successful.

创建了一个 bash 脚本,可以将文件发送到 sftp,但如果传输成功,我想发送电子邮件。

 #!/bin/bash
 HOST=hostname.domain
 PORT=22
 USER=username
 PASSWORD=password
 SOURCE_FILE=path/filename
 TARGET_DIR=PATH

 /usr/bin/expect<<EOD

 spawn /usr/bin/sftp -o Port=$PORT $USER@$HOST
 expect "password:"
 send "$PASSWORD\r"
 expect "sftp>"
 send "put $SOURCE_FILE $TARGET_DIR\r"
 expect "sftp>"
 send "bye\r"
 EOD

Now i want if the above transfer is successfull send Success Email if not Failure email with error message.

现在我想如果上面的传输成功发送成功电子邮件,如果不是带有错误消息的失败电子邮件。

Please help!!

请帮忙!!

Thanks.

谢谢。

回答by Ancientt

You could pipe error info from your script to a file and grep for an error with a second script. The second script could even run the first and might look something like this:

您可以将脚本中的错误信息通过管道传输到文件,并使用第二个脚本 grep 查找错误。第二个脚本甚至可以运行第一个,可能看起来像这样:

/path/firstscript.sh 2>&1 > results.txt
if [ -n "$(grep 'error expected' results.txt)" ]
 then 
  echo "Found error" | mail -S "Error" [email protected]
 else
  echo "No error" | mail -s "Okay" [email protected]
 fi

Personally, I find it better to check for the file on the target site by doing a second connection and listing the output there. Then I check that second connection log for the existence of the uploaded file.

就我个人而言,我发现通过进行第二次连接并在那里列出输出来检查目标站点上的文件会更好。然后我检查第二个连接日志是否存在上传的文件。

I can't use rsync or key authentication with three different companies I script file transfers for, so I have some sympathy for people who get the answer "don't do that" when they ask a question. It's worse when you're searching for the answer because you already know that what people are recommending instead won't work.

我无法对我为其编写文件传输脚本的三个不同公司使用 rsync 或密钥身份验证,因此我对那些在提出问题时得到“不要这样做”答案的人表示同情。当你在寻找答案时情况更糟,因为你已经知道人们推荐的东西是行不通的。

Here's examples more closely based on what I actually do:

以下是更接近于我实际工作的示例:

email_result.bash

email_result.bash

#!/bin/bash
./uploadfile_example.bash 2>&1 > log.txt
if [ -n "$(grep "$(date +%b' '%d)" log.txt|grep "testfile")" ]
 then
  echo "File uploaded" |mail -s "Test success" [email protected]
 else
  echo "File not uploaded" |mail -s "Test fail" [email protected]
 fi

uploadfile_example.bash

uploadfile_example.bash

#!/bin/bash
datestamp=$(date +%s)
/bin/cp -v testfile.txt testfile.${datestamp}.txt
HOST="localhost"
USER="testuser"
PASS="YourPasswordHere"

expect -c "
spawn sftp ${USER}@${HOST}
expect \"password: \"
send \"${PASS}\r\"
expect \"sftp>\"
send \"put testfile.${datestamp}.txt\r\"
expect \"sftp>\"
send \"ls -l testfile.${datestamp}.txt\r\"
expect \"sftp>\"
send \"bye\r\"
expect \"#\"
"

/bin/rm -vf testfile.${datestamp}.txt

回答by ganachoco

sftp is interactive shell, and when error occur, it prints error messages.

sftp 是交互式 shell,当发生错误时,它会打印错误消息。

But It is hard to parse error message.

但是很难解析错误消息。

In your case, I recommand to use scp ( http://linux.die.net/man/1/scp) command.

在你的情况下,我建议使用 scp ( http://linux.die.net/man/1/scp) 命令。

When fail to transfer file, scp will return error code to shell.

当传输文件失败时,scp 将返回错误代码给 shell。

回答by Deleted User

sftp can use ssh key authentication, which should be preferable over password login through expect, as you're currently doing. Apart from passing password that way resembling a rube goldberg contraption, having plaintext passwords in a script would be a nightmare of every system admin. As alternatives, using the same authentication mechanism, but very scriptable, are rsync over ssh, and scp. scp and sftp are merely ssh subsystems, server side. rsync can use ssh as tunnel for data transfer, and offers several advantages over sftp or scp.

sftp 可以使用 ssh 密钥身份验证,这应该比通过 expect 密码登录更可取,正如您目前所做的那样。除了以类似于 rube goldberg 装置的方式传递密码之外,在脚本中使用明文密码将是每个系统管理员的噩梦。作为替代方案,使用相同的身份验证机制,但非常可编写脚本,通过 ssh 和 scp 进行 rsync。scp 和 sftp 只是 ssh 子系统,服务器端。rsync 可以使用 ssh 作为数据传输的隧道,并且与 sftp 或 scp 相比具有多种优势。