通过 SSH 进行监控并在检测到更改时执行本地脚本

通过 SSH 进行监控并在检测到更改时执行本地脚本

我有一个环境,可以通过 Cygwin 通过 SSH 连接到 Linux 机器,但由于安全策略超出我的控制范围,所以不能以其他方式连接到 Linux 机器。

我需要在 Windows 计算机上自动执行任务,但通过从 Linux 计算机(即监视的文件夹或 Web 服务)拉取的脚本或参数来指示这些操作。

我如何构建它,以便我可以保持 SSH 连接打开,并在检测到此远程变量更改时,在 Windows 计算机上触发另一个 Cygwin 命令?

一个示例用例是带有参数的浏览器自动化。虽然我可以通过 git 存储库和每次运行前首先与最新代码同步的循环脚本来完成此操作,但我希望有更多的控制权,例如通过向下传递另一个变量或 shell 脚本来强制终止正在执行的线程。线。

更新:毕竟,还有另一种方法可以更改允许端口 22 连接的 Windows 防火墙,因此幸运的是不需要这种复杂的情况,但我喜欢下面列出的建议。

更新:看来这样的场景依然存在。虽然通过 SSH 直接访问系统允许执行任务,但这些任务是在 SSH 用户中沙箱化的,而不是我想要在其中运行 GUI 任务的网络域用户(本地 Cygwin 实例在域用户的域中执行时不存在问题)图形用户界面)。请参阅下面我的回答。

答案1

你可以在 Windows 机器上运行 sshd 吗?如果是,那么您可以打开一个隧道,以便 Linux 计算机可以向 Windows 计算机发送命令,如下所示:

ssh -R 2222:127.0.0.1:22 user@linuxmachine control-script

然后,control-script 将包含所有检查,如果必须在 Windows 计算机上执行某些操作,它将执行如下命令:

ssh -p 2222 user@localhost something.cmd

答案2

我使用了类似于 troydj 的答案,只需使用 watch 命令来执行一个“检查器”脚本,该脚本监视另一个脚本的存在并在发现时执行它。

在 Windows 的 Cygwin 上

watch -n 5 ~/checker.bash

检查器.bash

#!/bin/bash
if [ -f myscript.bash ]; then
 sh ~/myscript.bash
else
 echo 'checking...'
fi

myscript.bash(通过 SSH 启动 Visual Studio 2012 的示例)

#!/bin/bash
/cygdrive/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 11.0/Common7/IDE/devenv.exe
rm myscript.bash

在 Linux 机器上,我可以开发并创建脚本。然后,当我希望它们在登录用户 GUI 的 Windows 上执行时,我将脚本复制到该myscript.bash位置,该位置一旦被“检查器”脚本发现(由命令循环watch),就会在本地执行。

在本例中,我将最后一行添加到脚本中,以便在执行后将其自身删除。

这对于我的目标来说非常有效。如果没有这样的解决方法,让 Cygwin 通过 SSH 连接驱动特定 Windows 用户帐户中的进程通常很棘手。

答案3

如果您Expect的本地 Cygwin 机器上有,则可以使用它ssh进入远程 Linux 机器并监视假脱机目录中的作业。当检测到新工作时,Expect 脚本可以暂停ssh,在 Cygwin 系统上运行本地命令,然后恢复 ssh。它可能看起来像这样(作为基本的第一遍):

#!/usr/bin/expect

set timeout 10
log_user 1

spawn bash --login
expect -re {.*\$}       ;# Assumes a dollar sign in your prompt on local box

send "ssh remoteuser@your_remote_linux_box\r"
expect "*word:*"
send "REMOTE_PASSWORD\r"  ;# Bad security practice!!  For illustration purposes only.
expect -re {\r\n.*\$}     ;# Assumes a dollar sign in your prompt on your remote box
puts "Connected to remote system"

set i 0

while {$i < 5} {     ;# For now, we just loop 5 times. You might loop forever...
    send "ls ~/TasksSpoolDir | wc -l\r";
    expect -re "\r\n(\[0-9\]+)\r"
    set taskcount $expect_out(1,string)
    sleep 1
    if { $taskcount } {
            # Inspect remote job files from spool directory, for example, to determine what you want to do locally
            send "\r~\032"             ;# Send ~CTRL-Z to ssh
            expect "Stopped"
            send "pwd; ls; echo Do local tasks now.  Remove remote job files from spool directory...\r"
            sleep 1
            send "fg\r"                ;# Resume ssh.
            sleep 1
            send "\r\r"
            expect -re {\r\n.*\$}      ;# Assumes a dollar sign in your prompt on your remote box
    }

    incr i
    sleep 1;  # Sleep however long between checks for new work from spool directory
}

send "exit\r"
expect -re {.*closed}
puts "Connection to remote host closed..."
send "exit\r"
expect "*"
puts "Local bash process closed..."
wait

exit 0

相关内容