【问题标题】:Where to put <<EOF when looping using sshpass?使用 sshpass 循环时在哪里放置 <<EOF?
【发布时间】:2024-04-17 02:15:01
【问题描述】:

我正在使用以下脚本循环浏览本地文件夹中的所有文件,并使用sshpass 将它们上传到sftp 位置。我已经尝试过put 语句来上传单个文件。但不知怎么,我的&lt;&lt;EOFEOF 的正确放置位置有问题?还是缺少其他东西?

#!/bin/bash

FILES= /MY_LOCAL_FOLDER_PATH/*
sshpass -p 'MY_PASSWORD' sftp -o StrictHostKeyChecking=no -o HostKeyAlgorithms=+ssh-dss MY_USERNAME@FTP_URL:/Import 
<<EOF
for f in $FILES   
do
chmod +X $f
put $f
done
EOF

我把chmod 放在那里是因为我的文件“权限被拒绝”。

【问题讨论】:

  • 我宁愿推荐你使用批处理文件而不是使用 IO 重定向进行 harakiri。
  • @Jakuje 这一切都在.sh 文件中。如果您有任何解决方案,将很高兴看到您的解决方案。

标签: bash shell ssh sshpass


【解决方案1】:

如果您想为sftp 生成put 命令作为输入,您必须通过管道传输它们。您不能在 here-document 中处理循环。此外,您不应该使用sshpass -p,因为该程序的命令行通过procps 对系统上的所有进程都是可见的,即使是其他用户的也是如此。 (非常简短,但无论如何都是可见的。)环境变量只对同一个用户可见,但一般来说,ssh 键可能仍然更可取。

这样的事情可能会奏效:

#!/bin/bash
export SSHPASS=MY_PASSWORD
for f in /path/* ; do 
    echo put "$f"
done | sshpass -e sftp user@whereever:/path
unset SSHPASS

循环内的任何命令都在本地执行,任何你想作为命令传递给sftp 的命令都应该通过echo 或类似的方式打印。 (当然,这些命令不应该打印任何不应该发送到sftp 的内容。)

【讨论】:

  • export SSHPASS=xxx 行是做什么的,我应该为“xxx”值写什么?
  • @Disasterkid, export var=value 为命名变量分配一个值并将其标记为导出,以便它在脚本启动的命令环境中可见
【解决方案2】:

尝试在sshpass之后的行尾使用&lt;&lt;EOF

#!/bin/bash

FILES= /MY_LOCAL_FOLDER_PATH/*
sshpass -p 'MY_PASSWORD' sftp -o StrictHostKeyChecking=no \
    -o HostKeyAlgorithms=+ssh-dss MY_USERNAME@FTP_URL:/Import <<EOF
for f in $FILES   
do
chmod +X $f
put $f
done
EOF

【讨论】:

  • $f 需要反斜杠转义。 ($f => \$f)
  • sftp 不支持for 命令,所以你只会得到一些Invalid command. 错误