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

anu*_*ava 163 unix ssh bash shell sftp

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

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

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

anu*_*ava 170

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

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

如果您决定给sshpass一个机会,那么这是一个可行的脚本片段:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!
Run Code Online (Sandbox Code Playgroud)

  • 我想,无需出口.`SSHPASS =密码sshpass -e ...`应该这样做. (17认同)
  • 我能够做一个单行来下载日志文件:`sshpass -p"my_password"sftp -oPort = 9999 user @ host:dir/file.log` (9认同)
  • `-oBatchMode = no`对我来说是至关重要的缺失部分. (8认同)
  • @gorus:One-liner很酷但是我不想在命令行上使用密码,因为增强了窥探风险. (6认同)
  • 在Mac上使用它:http://stackoverflow.com/questions/9102557/sftp-command-in-bash-script-with-mac-os-x/9102723#9102723 (3认同)
  • 您可以添加 `&gt; ~/file.out 2&gt;&amp;1` 将输出和 stderr 重定向到文件。 (2认同)

小智 91

另一种方法是使用lftp:

lftp sftp://user:password@host  -e "put local-file.name; bye"
Run Code Online (Sandbox Code Playgroud)

此方法的缺点是计算机上的其他用户可以从类似工具读取密码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"
Run Code Online (Sandbox Code Playgroud)

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

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
Run Code Online (Sandbox Code Playgroud)

  • 您可以为lftp创建脚本文件,这样您就不必在命令行中提供密码.创建一个文件`put-script`:`open sftp:// user:password @ host; put local-file.name; exit`比运行`lftp -f put-script`这样你就不必在命令行中拥有用户名和密码,并且可以为脚本文件设置限制性权限. (10认同)
  • +1表示替代方案,但我们可以避免在命令行上提供密码吗? (9认同)
  • 执行“lftp”比使用“sftp”和“sshpass”容易得多。好答案。 (5认同)
  • @AaronDigulla 赞成,因为这正是 OP 所要求的 - “一种从 Bash 脚本内部运行 sftp 命令(**使用**提供的用户名/**密码**)的方法”。 (3认同)
  • 因向同一台计算机上的任何人显示密码而被否决 (2认同)

rez*_*ter 50

Expect是一个很棒的程序.

在Ubuntu上安装它:

sudo apt-get install expect
Run Code Online (Sandbox Code Playgroud)

在CentOS机器上安装它:

yum install expect
Run Code Online (Sandbox Code Playgroud)

假设您要连接到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
Run Code Online (Sandbox Code Playgroud)

这将打开与您的服务器密码的sftp连接.

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

这会从/ var/log /中找到的本地目录上传日志文件,文件名为file.log,远程服务器上的"logdirectory"


Mik*_* S. 23

您可以在shell脚本中以交互方式使用lftp,以便通过执行以下操作将密码保存在.bash_history或类似内容中:

vi test_script.sh
Run Code Online (Sandbox Code Playgroud)

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

#!/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
Run Code Online (Sandbox Code Playgroud)

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

  • 要覆盖现有文件,请在lftp << END_SCRIPT之后添加"set xfer:clobber on" (2认同)

小智 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"
Run Code Online (Sandbox Code Playgroud)

我想我应该分享这些信息,因为我在运行help命令(sftp -h)之前查看了各种网站,并且我很惊讶地看到密码选项.

  • 给你+1好建议.但是,这将要求您在命令行上传递密码,并且执行`ps`命令的系统上的任何人都可以看到您的密码. (9认同)
  • 我试过了,我得到了'未知选项 - - 用法: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` (4认同)
  • @ihue 可能是因为您需要 **Techia SSH**,而不是 OpenSSH (2认同)

Sri*_*niV 17

您可以通过启用无密码验证来覆盖.但是你应该在开始之前安装密钥(pub,priv).

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

Local $> ssh-keygen -t rsa 
Run Code Online (Sandbox Code Playgroud)

按ENTER键以显示所有选项.不需要键入任何值.

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD
Run Code Online (Sandbox Code Playgroud)

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

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD
Run Code Online (Sandbox Code Playgroud)

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

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit
Run Code Online (Sandbox Code Playgroud)

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

$> ssh user@targetmachine
Run Code Online (Sandbox Code Playgroud)

  • +1为你的答案,但问题是关于在没有公钥/私钥的情况下执行此操作。 (2认同)

ASa*_*our 17

我发现实现此目的的最简单方法是结合使用CURLSFTP ,而无需安装任何第三方库(例如ExpectSSHPASS ...等) 。这两个几乎存在于每台 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"
Run Code Online (Sandbox Code Playgroud)

例子:

curl  -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"
Run Code Online (Sandbox Code Playgroud)

解释:

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

  • 这不是相反的方向吗?这显示了当问题是从本地上传到远程时如何将文件从远程服务器复制到本地。 (2认同)
  • 显示错误:libcurl 中不支持或禁用“sftp” (2认同)

Ric*_*ing 7

将sshpass与一个锁定的凭证文件结合起来,实际上,它与任何东西一样安全 - 如果你在盒子上有root来读取凭证文件,那么所有赌注都会被取消.


Eri*_*ski 5

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

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "
Run Code Online (Sandbox Code Playgroud)

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


rav*_*jan 5

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

  1. 为Ubuntu安装sshpass - sudo apt-get install sshpass
  2. 如果是Ubuntu首次将远程IP添加到已知主机文件 - > 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