I want to execute an sh script on a remote Windows 10 computer without logging into interactive shell.
On Linux I would do something like
ssh user#machine "echo execute program automatically && ./my_program "
However when I ssh into my Windows 10 machine using open-ssh server it opens by default cmd. In interactive mode I would now open git-bash
"C:\Program Files\Git\bin\sh.exe" --login
Then execute my script from there.
When I try to combine the commands like this
ssh user#machine ' "C:\Program Files\Git\bin\sh.exe" --login && ./my_program " '
the shell freezes. Without the single quotes, the command also doesn't work (obviously).
So what to do?
Try to change default shell, with administrator CMD :
reg add HKLM\SOFTWARE\OpenSSH /v DefaultShell /d "C:\Program Files\Git\bin\sh.exe"
Related
I would like to be able to reboot WSL sessions. To do so is a little awkward as WSL does not use systemd so we cannot use reboot. Within a WSL session, we can run any Windows executable:
boss#Asus: ~ $ wsl.exe -l -v
NAME STATE VERSION
* Ubuntu-20.04 Running 2
fedoraremix Stopped 1
Alpine Stopped 1
Ubuntu Stopped 1
Therefore, we can use wsl.exe (you have to make sure to always add .exe when calling Windows commands or they will not work) to shutdown the currently running WSL session wsl.exe -t Ubuntu-20.03, but the problem is that I don't know the session name.
When we are inside a WSL session, hostname is something different, and so I don't know how to find the name of the currently running session that I am inside (maybe a Windows process command that tells me what process I am running from??).
Ideally, I would like a command to equate to a reboot. I guess this would have to look something like:
Run an asynchronous command that will initiate a new session 5-10 seconds in the future to allow the previous session to fully shutdown (and that will not terminate when this session is terminated).
Terminate the currently running session with wsl.exe -t <my found name>.
A few seconds later, the new session will start up.
Credits to the commenters above.
To shutdown a session from within a WSL guest, you can run:
wsl.exe --terminate $WSL_DISTRO_NAME
Rebooting is also possible, however so far I do not know how to get a new terminal inside the same console window. The following will reboot the WSL guest and open a new console window of it when it has finished:
cd /mnt/c/ && cmd.exe /c start "rebooting WSL" cmd /c "timeout 5 && wsl -d $WSL_DISTRO_NAME" && wsl.exe --terminate $WSL_DISTRO_NAME
Explanation:
From the perspective of Windows, WSL systems are mounted as network resources. cmd does not support the resulting UNC path formats such as \\wsl$\Debian\<...>. Therefore it may be best to cd to a directory it can resolve as a Windows path instead, such as C:\, before it is executed. If ommited, cmd will complain and change its directory to cmd's %windir%.
&& runs another command after the previous one has finished in linux and windows cmd.
cmd.exe /c starts a cmd instance and tells it to execute a command that follows.
start "<WindowTitle>" ... is a cmd-internal command to run another program inside its own window, independent of the cmd instance. In this case the program is another cmd window. It will not be affected when WSL shuts down.
In the original Linux-Terminal, the first cmd /c command has finished, and the third command after && shuts down the guest like above.
The second cmd window waits for a few seconds, then starts a new WSL session of the same WSL machine.
Creating an Alias
You can make this easier to use by creating an alias. For bash users, edit your ~/.bashrc file and apply the changes afterwards:
nano ~/.bashrc && source ~/.bashrc
Add either or both of the lines below anywhere in the file.
You can of course choose any name you want. Both shutdown and reboot exist as systemd commands, but since they do not work in WSL machines, you can replace them with an alias as follows:
alias shutdown='wsl.exe --terminate $WSL_DISTRO_NAME'
alias reboot='cd /mnt/c/ && cmd.exe /c start "rebooting WSL" cmd /c "timeout 5 && wsl -d $WSL_DISTRO_NAME" && wsl.exe --terminate $WSL_DISTRO_NAME'
Expanding on the ansver from #BasementScience
To manage a remote WSL I've set up a Windows TaskScheduler job to start wsl with an /etc/init-wsl which in turn starts cron, ssh, rsyslog and autossh (so I can connect back to WSL).
So naturally I'm keen to get these processes started also on a remote WSL reboot, so I'm able to login again afterwards.
# Added to $HOME/.bashrc - Renamed aliases to separate from OS commands
alias wslshutdown='wsl.exe --terminate $WSL_DISTRO_NAME'
alias wslreboot='cd /mnt/c/ && cmd.exe /c start "Rebooting WSL" cmd /c "timeout 5 && wsl -d $WSL_DISTRO_NAME" -- sudo /etc/init-wsl && wsl.exe --terminate $WSL_DISTRO_NAME'
The detail is here ... & wsl -d $WSL_DISTRO_NAME" -- sudo /etc/init-wsl & ...
This will not start a new shell, but will start my processes so I can login again.
The /etc/init-wsl script have to be created:
sudo touch /etc/init-wsl && sudo chmod 755 /etc/init-wsl
# Add services as needed
sudo bash -c 'cat << EOF > /etc/init-wsl
service ssh start
service cron start
EOF'
# Ensure your user (the %sudo group) can sudo the init script without password
sudo bash -c 'cat << EOF > /etc/sudoers.d/user-service
%sudo ALL=NOPASSWD: /usr/sbin/service *
%sudo ALL=NOPASSWD: /etc/init-wsl
EOF'
I prefer using the bash terminal to do work, on a Windows system, I would install Git bash to do work.
Recently I have the need to access a windows machine remotely, via SSH. But I find that once I SSH into the windows system I enter into the command prompt. I have tried to activate Git Bash by using:
> "C:\Program Files\Git\git-bash.exe"
But to no avail. How do I access Git-bash via ssh?
Turns out the command I should run is
> "C:\Program Files\Git\bin\sh.exe"
I have to zip files on a remote windows machine.
So I first ssh to the windows machine
ssh my_user#my_host "cd /d D:\MyFolder"
And the above command works.
However if I try to run any command after that it fails.
So if I do something like
ssh my_user#my_host "cd /d D:\MyFolder; dir"
The system cannot find the path specified.
You can try something like:
ssh my_user#my_host <<EOF
cd /d D:\MyFolder
dir
EOF
The second EOF should be alone on the line and start from the begin
is it possible to use cygwin from cmd.exe in Windows?
i want to do following
FOR /L %G in (1 1 100) DO sshpass -p "password" scp E:\in\File%G.csv openstack#remotecomp:/testfiles/
transfer 100 files from windows to unix computer
now question:
can i use sshpass and scp from cmd.exe as long as cygwin is installed? or do i have to use cygwin terminal?
and do the files which i want to transfer neccessarily have to be in cygwin's folder?
goal is to use this one command in a BPEL activity, and as such there should not be any kind of user interaction when the command is run
You can use the full paths to the binaries, or create a wrapper script and call that to do the cygwin commands, e.g.
#!/bin/bash
# doit.sh wrapper script in home dir of cygwin user
echo "got args $#"
and call it from windows shell with
for /L %G in (1 1 100) DO c:\cygwin\bin\bash --login -c "/home/youruser/doit.sh %G"
in this case it prints 1..100 out, but your wrapper script can do all the ssh stuff it needs to instead.
For a more complex script, you can pass params from windows to the shell script like this:
#!/bin/bash
# callssh.sh
COUNT_NUM=$1
PASSWORD=$2
FILE_PATH=$(cygpath $3)
sshpass -p $PASSWORD scp $FILE_PATH openstack#whereever:/some/path/
and you'd call it with
for /L %G in (1 1 100) DO c:\cygwin\bin\bash --login -c "/home/youruser/callssh.sh %G your_password E:/in/File%G.csv"
Note the use of cygpath to convert from windows path style to something that cygwin understands. The SSH executable is a cygwin process so you need to convert to something it will be able to use.
Also, note the change from backslashes to forward slashes, again for some quirks in path separators between windows and cygwin.
If you have trouble with this (I can't test your code for you directly), then do this on a cygwin shell:
cygpath E:/path/to/file
and then check it outputs something like /e/path/to/file (or /cygpath/e/path/to/file if you haven't remapped our root drives).
I am developing a TIBCO application and need to be able to run a scp command from an external command resource.
Anyway the issue boils down to being able to log in to bash.exe then run my scp command in the same line.
it works when I run (from cmd.exe)
c:\cygwin\bin\bash.exe --login
(I enter bash)
Then I can run my scp statement just fine
scp account#server:~mysourcedirectory/targetfilename* /cygdrive/c/targetfolder
I want to do these two things in the same line but it doesnt work, aka
c:\cygwin\bin\bash.exe --login -c scp account#server:~mysourcedirectory/targetfilename* /cygdrive/c/targetfolder
will fail. What am I doing wrong and how can i run this command in one go?
Thanks
You have to quote the command.
c:\cygwin\bin\bash.exe --login -c "scp account#server:~mysourcedirectory/targetfilename* /cygdrive/c/targetfolder"
Tested using cmd in wine in gnu/linux. Single quotes did not work, I don't know all the quoting rules for cmd. But the above did work.