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

时间:2011-03-22 03:40:24

标签: bash shell unix ssh sftp

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

那么有没有办法通过cron作业从Bash脚本中运行sftp命令(提供用户名/密码)?

我发现了一个类似的Stack Overflow问题, Specify password to sftp in a Bash script ,但我的问题没有令人满意的答案。

11 个答案:

答案 0 :(得分:153)

除了使用公钥认证之外,您还有一些选择:

  1. 使用keychain
  2. 使用sshpass(安全性较低,但可能符合您的要求)
  3. 使用expect(最不安全且需要更多编码)
  4. 如果您决定给sshpass一个机会,那么这是一个可行的脚本片段:

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

答案 1 :(得分:85)

另一种方法是使用lftp:

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

此方法的缺点是计算机上的其他用户可以从ps等工具读取密码,并且密码可以成为shell历史记录的一部分。

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

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

LFTP还包括一个很酷的镜像功能(可以包括确认传输后删除' - 删除源文件'):

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

答案 2 :(得分:45)

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”

答案 3 :(得分:21)

您可以在shell脚本中以交互方式使用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

编辑/ {1}}的put文件的主机,用户,传递和目录后编写/退出vi编辑器。然后使脚本可执行:wq并执行它{{1} }。

答案 4 :(得分: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

答案 5 :(得分:15)

我最近被要求从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)之前查看了各种网站,并且我很惊讶地看到了密码选项。

答案 6 :(得分:7)

将sshpass与一个锁定的凭据文件相结合,实际上,它与任何东西一样安全 - 如果你已经在框中找到了根文件来读取凭证文件,那么所有投注都会被取消。

答案 7 :(得分:5)

Bash程序等待sftp请求密码然后发送:

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

您可能需要安装expect,更改密码&#39;的措辞。小写&#39; p&#39;匹配您的提示收到的内容。这里的问题是它以纯文本形式在文件中以及命令历史中公开您的密码。这几乎打破了首先获得密码的目的。

答案 8 :(得分:5)

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

  1. 为Ubuntu安装sshpass - sudo apt-get install sshpass
  2. 如果是第一次将远程IP添加到已知主机文件中 对于Ubuntu - &gt; ssh user @ IP - &gt;输入'yes'
  3. 为它提供scp和sshpass的组合命令。 下面是战争应对远程tomcat的示例代码 sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps

答案 9 :(得分:2)

我找到的最简单的方法是使用 ExpectSSHPASS...等第三方库,而不用安装任何第三方库>CURL 和 SFTP。这两个几乎在每台 Linux 机器中都有。

这是更改值后应执行的命令。

curl  -k "sftp://SERVER_IP:SERVER_PORT/FULL_PATH_OF_THE_FILE" --user "SERVER_USER:SERVER_PASSOWRD" -o "THE_NAME_OF_THE_FILE_AFTER_DOWNLOADING_IT"

示例:

curl  -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"

解释:

我们正在使用用户名 admin 和密码 123456 连接到服务器 10.10.10.10:77,以移动文件 /home/admin/test.txt 从该服务器到您当前使用的服务器来执行上述命令。

答案 10 :(得分:1)

您可以使用带有 scp 和 os 库的 Python 脚本进行系统调用。

  1. ssh-keygen -t rsa -b 2048(本地机器)
  2. ssh-copy-id user@remote_server_address
  3. 创建一个 Python 脚本,例如:
    import os
    cmd = 'scp user@remote_server_address:remote_file_path local_file_path'
    os.system(cmd)
  1. 在 crontab 中创建一个规则来自动化你的脚本
  2. 完成