【问题标题】:Provide commands automatically to ftp in bash script在 bash 脚本中自动向 ftp 提供命令
【发布时间】:2023-11-04 07:19:01
【问题描述】:

我正在尝试使用 ftp 创建一个 bash 脚本。

如果我使用终端并将命令一个接一个地放在下面,它就像一个魅力。

$ ftp 192.168.1.4 2121
Connected to 192.168.1.4.
220 SwiFTP 1.7.11 ready
Name (192.168.1.4:user): 
331 Send password
Password:
230 Access granted
Remote system type is UNIX.
Using binary mode to transfer files.

ftp> cd Study/Math
ftp> put ~/Documents/Math/lesson.pdf lesson.pdf

我正在尝试使用 bash 脚本自动执行此命令:

#!/bin/bash
ftp 192.168.1.4 2121
cd Study/Math
put ~/Documents/Math/lesson.pdf lesson.pdf

它不工作。我知道ftp 是一个独立的工具,我必须在ftp 程序运行时输入这些命令。我在网上搜索了各种技术(如printfexpect 等),但没有奏效。我还尝试使用互联网上的一些脚本来自动化这个过程,但没有任何帮助。我是 bash 脚本和这些东西的新手。你们能帮我解决这个问题吗? 提前谢谢...

【问题讨论】:

标签: linux bash shell ftp


【解决方案1】:

首先,如果您有其他选择,请不要这样做。这是一个相当标准的成语,但它确实在很多方面都被打破了。如果您非常确定它永远不会做任何不可预测的事情,并且当它发生时它无论如何都可以,那么当然可以,但总的来说......

1) 使用 ftp 以外的东西。例如,scp 运行良好,并且有一个实际有用的可检查返回码。

2) 对模块使用更精细的编程语言。不要误会我的意思,我喜欢 bash,并且总是会在可能的情况下首先使用它,但是如果没有任何简单的方法来检查每个命令是否有效,就将命令流泵入 ftp,就像一个即发即弃的 UDP 鱼雷一样习惯。尝试 Perl、Python 或任何其他可让您检查每个命令的返回码并做出相应反应的该死的东西。 :)

3) 如果您必须使用 bash(是的,我已经做到了),并且如果它足够重要以检查(什么不是?),那么请考虑您将如何做到这一点。也许您可以将 course.pdf 拉回本地 testme.pdf 和 cmp 以确保它很好,这似乎很容易。对于任何更复杂的脚本,您可能需要将 ftp 作为协同进程运行并一次提供一个命令,然后读回它的输出并解析返回码,因为 ftp 通常只在那里报告错误......并注意“已发送 500 字节”,这不是 500 错误。

无论如何,祝你好运。在许多方面,简单仍然是最好的。

【讨论】:

    【解决方案2】:

    虽然您正在使用的 ftp 方法可能适合您的目的,但如果服务器未按预期响应,它将无法正常运行。

    正如已经建议的那样,尽可能使用 ftp 以外的东西。使用密钥身份验证的 scp 或 rsync 会更好,更方便,因为每次更改密码时它都不会中断,并且更安全。

    【讨论】:

      【解决方案3】:

      好的,在User123给我link之后,我终于解决了我的问题。所以,我给出了我的工作脚本。

      #!/bin/sh
      
      HOST='192.168.1.4 2121'
      USER='username_of_ftp'
      PASSWD='password_of_ftp'
      
      /usr/bin/ftp -n $HOST <<END_SCRIPT
      user ${USER} ${PASSWD}
      cd Study/Math
      put ~/Documents/Math/lesson.pdf lesson.pdf
      quit
      END_SCRIPT
      
      exit 0
      

      【讨论】:

      • ftp的用户完整路径更好,如:/usr/bin/ftp -n 92.168.1.4 2121 &lt;&lt;EOF,您可以通过命令获取路径:which ftp
      • "将lesson.pdf 拉回本地testme.pdfcmp 以确保它是好的"...?
      【解决方案4】:

      你可能对所谓的heredoc感兴趣

      #!/usr/bin/env bash
      ftp -n 92.168.1.4 2121 <<EOF
      cd Study/Math
      put ~/Documents/Math/lesson.pdf lesson.pdf
      EOF
      

      由于 ftp 程序从/dev/stdin 读取其输入,您可以使用heredoc 来定义应该从/dev/stdin 传递的内容

      【讨论】:

      • 使用ftp -n 92.168.1.4 2121 &lt;&lt;EOF,然后在脚本中定义用户名和密码,例如:user $user_name $passwd,会不会更安全!
      • 我同意,但我不同意将密码放入脚本中。这显然是他想要的OP。他的问题在这件事上并不清楚。
      • 感谢您的帮助。安全不是我的首要任务...我尝试了您的脚本但无法正常工作。它显示“ftp:连接:连接超时”
      • 好的。现在我看到服务器是 192.168.1.4,但我放的是 92.168.1.4。所以,它不起作用。
      • 请注意,常见的ftp 实现不接受命令行上的端口号,仅在open 命令中。