【问题标题】:How can I scp a file and run an ssh command asking for password only once?如何 scp 文件并运行 ssh 命令仅要求输入一次密码?
【发布时间】:2011-09-10 06:07:24
【问题描述】:

这是问题的上下文:

为了让我能够在工作中打印文档,我必须将文件复制到另一台计算机,然后从该计算机打印。 (不要问。这很复杂,没有其他可行的解决方案。)两台计算机都是 Linux,我在 bash 中工作。我目前执行此操作的方式是将文件scp 传递到打印计算机,然后将ssh 输入并从命令行打印。

这是我想做的:

为了让我的生活更轻松,我想将这两个步骤合二为一。我可以轻松编写一个完成这两个步骤的函数,但我必须提供两次密码。有什么方法可以组合这些步骤,以便我只提供一次密码?

在有人建议之前,基于密钥的 ssh 登录不是一种选择。出于安全原因,它已被管理员特别禁用。

解决方案:

我最终对 Wrikken 提供的第二个解决方案进行了修改。简单地将他的第一个建议包含在一个函数中就可以完成工作,但我喜欢能够打印多个文档而无需为每个文档输入一次密码的想法。我有一个相当长的密码,而且我是一个懒惰的打字员:)

所以,我所做的是获取一系列命令并将它们包装在 python 脚本中。我使用 python 是因为我想参数化脚本,而且我发现在 python 中最容易做到。我作弊,只是通过 os.system 从 python 运行 bash 命令。 Python 只是处理参数化和流控制。逻辑如下:

if socket does not exist:
    run bash command to create socket with timeout
copy file using the created socket
ssh command to print using socket

除了使用超时之外,我还在我的 python 脚本中添加了一个选项来手动关闭套接字,如果我希望这样做的话。

如果有人想要代码,请告诉我,我会将其粘贴到 bin 或放在我的 git 存储库中。

【问题讨论】:

  • Ack,完全忘记了。事实上,基本上,ssh-agent 与我的第二个答案基本相同,而且麻烦更少。
  • @Daenyth 据我所知,ssh-agent 不起作用。据我了解,ssh-agent 使用公钥身份验证,已在服务器端(打印机)禁用。
  • 如果您的管理员“出于安全原因”关闭密钥登录,他们就是无能的。密钥比基于密码的登录安全得多。
  • @Daenyth 你正在向合唱团布道。然而,我认为他们的理由是,他们不能相信用户会保护他们的密钥安全。他们别无选择,只能允许密码,他们宁愿只担心一个入口点而不是两个入口点。我在大学环境中,这意味着我们的工作站只比公开访问的要好一点。

标签: linux bash ssh scp


【解决方案1】:
ssh user@host 'cat - > /tmp/file.ext; do_something_with /tmp/file.ext;rm /tmp/file.ext' < file.ext 

另一种选择是只打开一个 ssh 隧道:

在 ~/.ssh/config:

Host *
        ControlMaster auto
        ControlPath ~/.ssh/sockets/ssh-socket-%r-%h-%p

.

$ ssh -f -N -l user host
(socket is now open)

后续的 ssh/scp 请求将重用已经存在的隧道。

【讨论】:

  • 第二个解决方案就像一个魅力。我想向未来的读者指出,但是第三个开关是小写字母 L,而不是数字 1。我花了几分钟才意识到你没有告诉我使用协议 1。我还有一个两部分问题。首先,这是否只留下与服务器的开放连接?如果是,我该如何手动关闭此连接?
  • 是的,确实如此,您可以使用ssh -S &lt;path to socket&gt; -O exit something 关闭它。是的,something,你可以用服务器的名字,你的猫的名字,只要有参数代替something....
  • 或者,如果您知道自己只是在有限的时间内忙碌,您可以使用 ssh -f user@host sleep 10; 而不是 ssh -f -N -l user host 打开套接字,其中 10 是保持打开状态的秒数.
  • 为了更接近“完美”:第一个“猫”不是必需的。只需使用重定向: ssh user@host "cat -> file.sh; ./file.sh"
  • 确实是无用猫的另一个候选者,我倾向于经常成为它的牺牲品......
【解决方案2】:

这是 bash 脚本模板,它跟在 @Wrikken's second method 之后,但可以直接使用 - 无需编辑用户的 SSH 配置文件:

#!/bin/bash

TARGET_ADDRESS=$1 # the first script argument
HOST_PATH=$2 # the second script argument
TARGET_USER=root
TMP_DIR=$(mktemp -d)
SSH_CFG=$TMP_DIR/ssh-cfg
SSH_SOCKET=$TMP_DIR/ssh-socket
TARGET_PATH=/tmp/file

# Create a temporary SSH config file:
cat > "$SSH_CFG" <<ENDCFG
Host *
        ControlMaster auto
        ControlPath $SSH_SOCKET
ENDCFG

# Open a SSH tunnel:
ssh -F "$SSH_CFG" -f -N -l $TARGET_USER $TARGET_ADDRESS

# Upload the file:
scp -F "$SSH_CFG" "$HOST_PATH" $TARGET_USER@$TARGET_ADDRESS:"$TARGET_PATH"

# Run SSH commands:
ssh -F "$SSH_CFG" $TARGET_USER@$TARGET_ADDRESS -T <<ENDSSH
# Do something with $TARGET_PATH here
ENDSSH

# Close the SSH tunnel:
ssh -F "$SSH_CFG" -S "$SSH_SOCKET" -O exit "$TARGET_ADDRESS"

【讨论】:

    猜你喜欢
    • 2013-11-24
    • 2019-09-29
    • 1970-01-01
    • 2022-01-08
    • 2019-08-25
    • 2013-07-22
    • 1970-01-01
    • 2013-09-30
    • 2012-04-02
    相关资源
    最近更新 更多