Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash脚本:使用Expect将文件发送到SFTP_Bash_Shell_Unix_Sftp_Expect - Fatal编程技术网

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

Bash脚本:使用Expect将文件发送到SFTP,bash,shell,unix,sftp,expect,Bash,Shell,Unix,Sftp,Expect,我必须将几个gzip文件从本地服务器发送到SFTP服务器 我的服务器信息 分发服务器ID:Ubuntu 说明:Ubuntu 12.04.4 LTS 发行日期:12.04 代号:精确 创建了一个bash脚本,可以将文件发送到sftp,但如果传输成功,我想发送电子邮件 #!/bin/bash HOST=hostname.domain PORT=22 USER=username PASSWORD=password SOURCE_FILE=path/filename TARGET_DIR=

我必须将几个gzip文件从本地服务器发送到SFTP服务器

我的服务器信息

分发服务器ID:Ubuntu 说明:Ubuntu 12.04.4 LTS 发行日期:12.04 代号:精确

创建了一个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
#/bin/bash
HOST=hostname.domain
端口=22
用户=用户名
密码=密码
SOURCE\u FILE=路径/文件名
TARGET_DIR=路径

/usr/bin/expectsftp是交互式shell,当出现错误时,它会打印错误消息

但很难解析错误消息

在您的情况下,我建议使用scp()命令


当无法传输文件时,scp将向shell返回错误代码。

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

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

/path/firstscript.sh 2>&1 > results.txt
if [ -n "$(grep 'error expected' results.txt)" ]
 then 
  echo "Found error" | mail -S "Error" you@example.com
 else
  echo "No error" | mail -s "Okay" you@example.com
 fi
就我个人而言,我发现最好通过第二次连接并在那里列出输出来检查目标站点上的文件。然后我检查第二个连接日志是否存在上传的文件

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

下面的例子更接近于我的实际工作:

电子邮件_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" you@example.com
 else
  echo "File not uploaded" |mail -s "Test fail" you@example.com
 fi
上传文件_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