如何使用Bash脚本中的密码运行sftp命令?


173

我需要使用sftp从Linux主机将日志文件传输到远程主机。我的操作组提供了相同的凭据。但是,由于我无法控制其他主机,因此无法与其他主机生成并共享RSA密钥。

那么,是否有一种方法可以sftp通过cron作业从Bash脚本内部运行命令(提供用户名/密码)?

我发现了一个类似的Stack Overflow问题,即在Bash脚本中为sftp指定密码,但是没有令人满意的答案。

Answers:


178

除了使用公共密钥身份验证之外,您还有其他选择:

  1. 使用钥匙扣
  2. 使用sshpass(安全性较低,但可能满足您的要求)
  3. 使用预期(最不安全,需要更多编码)

如果您决定给sshpass一个机会,请执行以下脚本片段:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!

3
对于使用它在Mac上:stackoverflow.com/questions/9102557/...
anubhava

18
我认为不需要出口。SSHPASS=password sshpass -e ...应该做。
詹斯

9
我能够单线下载日志文件:sshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
Cloud Artisans 2013年

6
@gorus:单线很酷,但是由于增强了监听的风险,我不想在命令行上使用密码。
anubhava 2013年

8
-oBatchMode=no对我来说是至关重要的缺失部分。
richardkmiller 2014年

99

另一种方法是使用lftp:

lftp sftp://user:password@host  -e "put local-file.name; bye"

这种方法的缺点是计算机上的其他用户可以从类似的工具中读取密码,ps并且该密码可以成为您的Shell历史记录的一部分。

自LFTP 4.5.0以来,可以使用一种更安全的替代方法来设置LFTP_PASSWORD环境变量并使用来执行lftp --env-password。这是一个完整的示例:

LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"

LFTP还包括一个很酷的镜像功能(在确认传输后可以包括删除--Remove-source-files):

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com

9
+1表示替代方案,但我们可以避免在命令行中提供密码吗?
anubhava

1
Downvoted用于显示密码给任何人在同一台计算机上
亚伦Digulla

10
您可以为lftp创建脚本文件,这样就不必在命令行中提供密码。创建文件put-scriptopen sftp://user:password@host; put local-file.name; exit 比运行lftp -f put-script 要好。这样,您就不必在命令行中输入用户名和密码,并且可以对脚本文件设置限制性权限。
obaranovsky

@obaranovsky这是一个好主意。我想知道是否要将其作为别名或函数添加到我的环境变量中,这是否安全并且可以对其他用户隐藏?
sdkks

1
lftpsftp和和混在一起要容易得多sshpass。好答案。
MeanEYE

53

Expect是一个很棒的程序。

在Ubuntu上,使用以下命令安装它:

sudo apt-get install expect

在CentOS机器上,使用以下命令进行安装:

yum install expect

假设您要建立与sftp服务器的连接,然后将本地文件从本地计算机上载到远程sftp服务器

#!/usr/bin/expect

spawn sftp username@hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact

这将打开一个sftp连接,并使用您的密码连接到服务器。

然后转到您要上传文件的目录,在本例中为“ logdirectory”

这将从/ var / log /找到的本地目录中的日志文件上载到文件名为file.log的远程服务器上的“ logdirectory”中


感谢您的回答,我曾希望将其作为实现此任务的选择之一。
anubhava

谢谢。我通过搜索找到了您的答案,使用了它,并成功建立了一个带有期望的脚本。刚发布了用于增强
力量

非常感谢您的回答,我已经对其进行了投票:)
anubhava 2013年

我正在使用它输入ssh私钥的密码。将相同的公用密钥放在所有服务器上,而只是定期轮换专用密钥密码比较方便。
sdkks

24

您可以在外壳程序脚本中以交互方式使用lftp,以便通过执行以下操作将密码保存在.bash_history或类似文件中:

vi test_script.sh

将以下内容添加到您的文件中:

#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>

cd <base directory for your put file>

lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT

编辑主机,用户,传递和目录以输入放置文件后,编写/退出vi编辑器,:wq然后使脚本可执行chmod +x test_script.sh并执行./test_script.sh


2
要覆盖现有文件,请在lftp << END_SCRIPT
Balaji Natarajan

17

最近,我被要求从ftp切换到sftp,以确保服务器之间的文件传输安全。我们正在使用Tectia SSH软件包,该软件包具有--password在命令行中传递密码的选项。

例如: sftp --password="password" "userid"@"servername"

批处理示例:

(
  echo "
  ascii
  cd pub
  lcd dir_name
  put filename
  close
  quit
    "
) | sftp --password="password" "userid"@"servername"

我以为我应该共享此信息,因为在运行帮助命令(sftp -h)之前,我正在浏览各种网站,我很惊讶地看到密码选项。


9
为您的好建议+1。但是,这需要您在命令行上通过密码,并且执行ps命令的系统上的任何人都可以看到您的密码。
anubhava 2013年

4
我尝试过,我得到了unknown option -- - usage: sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host
cyber8200 '17

1
@ihue可能是因为您需要Techia SSH,而不是OpenSSH
qris

17

您可以通过启用无密码身份验证来覆盖。但是您应该先安装密钥(pub,priv)。

在本地服务器上执行以下命令。

Local $> ssh-keygen -t rsa 

按ENTER键提示所有选项。无需输入任何值。

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD

使用以下命令连接到远程服务器

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD

在远程服务器上执行以下命令

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit

在本地服务器上执行以下命令以测试无密码身份验证。它应该没有密码连接。

$> ssh user@targetmachine

1
+1为您的答案,但问题是没有公钥/私钥的情况。
anubhava 2014年

哎呀..刚看到密钥共享的限制:)
SriniV 2014年

出于好奇lftp -p ${port} -u ${login_id},${password} ${ip_number},从外壳程序脚本中调用该命令时,会将它们打印到什么位置?除了sshpass以外,您还如何解决?
SriniV 2014年

我没有Mac和Linux都lftp依赖sshpass
anubhava 2014年

纯金。谢谢!:)
Nikolay Tsenkov

7

结合使用sshpass和锁定的凭据文件,实际上,它是一样安全的-如果您已经在root身份上可以读取凭据文件,则无论如何都无法进行。


5

Bash程序等待sftp要求输入密码,然后将其发送:

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "

您可能需要安装Expect,将“密码”的措词更改为小写字母“ p”,以匹配您的提示收到的内容。这里的问题在于,它以纯文本形式在文件以及命令历史记录中公开您的密码。首先,这几乎破坏了拥有密码的目的。


+1,但我认为您已清楚说明此方法存在的问题。
anubhava 2014年

5

您可以使用sshpass。以下是步骤

  1. 为Ubuntu安装sshpass- sudo apt-get install sshpass
  2. 如果是第一次,则将远程IP添加到您的已知主机文件中对于Ubuntu-> ssh user @ IP->输入'yes'
  3. 给出一个组合的scp和sshpass命令。以下是用于应对远程tomcat战争的示例代码 sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.