Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have an environment where I can SSH into a Linux machine via Cygwin, but not the other way around due to a security policy out of my control.

I need to automate tasks on the Windows machine but dictate these things to do from scripts or parameters PULL'd from the Linux machine (ie, a watched folder or web service).

How can I structure this so that I can keep an SSH connection open and upon detecting this remote variable change, trigger another Cygwin command on the Windows machine?

An example use case would be browser automation with parameters. While I could do this via a git repo and a recurring script that first syncs with latest code each time before running, I'd like to have more control, such as to force kill the executing thread via passing another variable or shell script down the line.

UPDATE: After all that, there was another method to change the Windows firewall which allowed port 22 connections, so this complicated case will thankfully not be required, but I like the suggestions listed below.

UPDATE: Seems the scenario still exists. Though getting direct access to the system via SSH allowed execution of tasks, these were sandboxed within the SSH user, not the network domain user that I wanted to run GUI tasks in (local Cygwin instance does not have the problems to execute within the domain user's GUI). See my answer below.

share|improve this question
    
This sounds very complicated. Which problem are you trying to solve? For a Linux dev environment with a shared folder, many people like to use Vagrant, for example. –  sr_ Nov 1 '13 at 6:55
add comment

3 Answers

Can you run sshd on the Windows machine? If yes then you could open a tunnel so that the Linux machine can send commands to the Windows machine like this:

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

control-script would then contain all your checks and if something has to be executed on the Windows machine it would execute a command like this:

ssh -p 2222 user@localhost something.cmd
share|improve this answer
    
that sounds promising if Windows is the one initiating the tunnel, will give it a try –  lalalalalalalambda Nov 1 '13 at 17:22
add comment

If you have Expect on your local Cygwin box, you can use it to ssh into your remote Linux box and watch for jobs in a spool directory. When new work is detected, the Expect script can suspend ssh, run local commands on the Cygwin system, and then resume ssh. It might look something like this (as a rudimentary first pass):

#!/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 wanna 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
share|improve this answer
    
thanks, that was the kind of solution I was envisioning, will try it out –  lalalalalalalambda Nov 1 '13 at 17:22
add comment

I used something similar to troydj's answer, by simply using the watch command that executes a "checker" script that monitors for the existence of another script and executes it if discovered.

on Windows' Cygwin

watch -n 5 ~/checker.bash

checker.bash

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

myscript.bash (example to launch Visual Studio 2012 via SSH)

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

On the Linux machine, I can develop away and create the scripts. Then when I want them executed on the Windows logged in user's GUI, I copy my script to the myscript.bash location, which once discovered by the "checker" script (being looped by the watch command), executes locally.

I added the last line to to the script to remove itself after execution, in this case.

This works really well for what I was aiming to do. Getting Cygwin to drive processes within a specific Windows user account via SSH connection is often tricky if not impossible without a workaround like this.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.