Automatically copying files from a Linux machine to a Windows machine - windows

I need to automatically copy files from a linux machine to a windows one every day.
I'm looking for something simple and secure like scp, rsync, sftp. Unfortunately, I'm at a loss of how to set this up on the Windows machine.
Does anyone know how to do this?

You can try mounting the Windows drive as a mount point on the Linux machine, using smbfs; you would then be able to use normal Linux scripting and copying tools such as cron and scp/rsync to do the copying.

You can find rsync for windows in cygwin, with that you can setup a rsync server on the windows box and run a cron job on your linux machine rsync'ing all the files to the windows machine. We used to do that and it worked fine.

"I'm at a loss of how to set this up on the Windows machine." Windows is the client or the server? At a loss means what, specifically? What can't you do?
"linux machine to a windows" can be done two ways.
Linux is client. Windows runs an FTP or SCP or SSH server. Linux has a client and pushes the file to Windows. Look at FileZilla for free windows FTP server. Also, windows often has an FTP service that's turned off. Turn it on.
Windows is client. Windows periodically pulls the file from the linux server. This is easier, since Linux already has all the necessary servers available. You do, howeveevr, need to start them on Linux.
There are scores of sftp, scp clients for Windows. Windows comes with an ftp client. Google for sftp client. You'll find WinSCP, Putty, filezilla, and list free country list of sftp clients.

I haven't used it in years now, but you could try Unison from http://www.cis.upenn.edu/~bcpierce/unison/
It could be done with 'smbclient', which acts much like an FTP client to a Windows share. Check out the manpage: man smbclient and look for ways to script it with the -c option, or man expect to drive it.
Here's how I'd probably do it though:
Pick which user you're going to be
when you sync the files. Log in as
this user and type 'id', and get the
numeric ID. You will use this ID in
step 4
Become 'root'
mkdir /mnt/sharename
Edit your /etc/fstab file and add an entry something like this. Replace the user ID of 500 with your user ID. Replace sharename with your windows share name. Replance WINDOWSHOSTNAME with your host name or IP address. If you don't know the shares, run smbclient -L WINDOWSHOSTNAME.
//WINDOWSHOSTNAME/sharename /mnt/sharename cifs credentials=/root/smblogin,uid=500,noauto,user 0 0
Edit /root/smblogin and put the following two lines in it
username=YOUR_WINDOWS_USERNAME
password=YOUR_WINDOWS_PASSWOD
Log in as the user from step 1.
Try mounting the share: mount /mnt/sharename
If that succeeds, then write a script to do it automatically. Let's call it 'backup.sh':
#!/bin/sh
df | grep -q /mnt/sharename
if test $? -ne 0 ; then
mount /mnt/sharename
fi
cp -r /path/to/dir /mnt/sharename/destination/
Use cron to run the script.
Type crontab -e
Put the following in the file:
PATH=/bin:/usr/bin
# Backup at 2:15 A.M. every day. Run 'man 5 crontab' for help on the time format
15 2 * * * /path/to/backup.sh

You may try WinSCP and its scripting support. And Windows support some kind of cron-like operation in its management stuff, don't they?

Related

How to SSH from local linux into specific directory on windows 10 remote

I want to ssh from my local linux computer into a specific directory on a windows 10 remote. The shell that is used on the remote is git bash. I don't want to keep changing the directory every time I log into my remote using ssh.
for linux remotes this is easily done using something like this:
ssh -t user#x.x.x.x "cd /targetDir ; \$SHELL --login"
The question is how can the same thing be achieved for Windows 10 remotes? If nothing else works I would also accept changing the default entry point in git bash for any ssh sessions on the remote.
Please note that I am not looking for help setting up ssh (already works). I just want to jump right into a specific directory when a session is started.
I was able to figure this thing out myself. The following command gets the job done. Using double and single quotes together is required to make it work (in no particular order).
ssh -t user#x.x.x.x "'cd /targetDir ; bash'"

Using scp to transfer files from unix to windows

I have a windows 7 laptop (not windows server, just a regular laptop). A unix machine is trying to drop a file to this windows machine. If i don't want to setup an FTP server on my windows, can the unix user still drop files using scp?
This may not be what you are looking for but can accomplish the same goal with relative ease. Using powercat you can set up a listener on the windows box and drop a file from the unix machine.
windows machine (listener):
powercat -l -p 8000 -of C:\file.txt
unix box (using native nc):
nc -nv ip_addr_of_windows_box 8000 < file.txt
Additionally, you could also run a server on the unix box and pull the files from the windows machine over http, though this isn't the safest method as you will be exposing the file system..
unix box:
python -m SimpleHTTPServer
windows (powershell):
Invoke-WebRequest https://ip_of_unix_box:8000/file.txt -OutFile c:\temp\file.txt

SCP file from ssh session to localhost

I have a headless file server on which I store and manage downloads and media, but occasionally I have to transfer small files back to my computer (Mac, using bash shell). The problem is that some files have more user-friendly names and commonly have spaces in them, and they are buried in the file directory hierarchy I have set up on my server.
When I'm using scp from my local machine, I don't have tab completion, so I have to manually type out the entire path and name with spaces escaped. When I ssh into the server first, the command:
scp /home/me/files/file\ name\ with\ spaces.png Me#localhost:/Users/Me/MyDirectory
fails with the error "Permission denied, please try again" even though I'm entering my local machine user password properly.
I've learned a little bit of sftp since I've been told that may be a better tool for file transfer. However, the utility seems outdated and I still don't have tab completion after establishing a connection to the server (on my Terminal when pressing Tab I just get a tab character).
My question is this: what can I do to allow tab completion while using scp from my Mac? Or am I using incorrect syntax for scp while in an ssh session, and is there something in that command I should fix? Or, is there a (better? newer?) tool other than sftp that would offer tab completion on a server?
Finally, if none of these problems have simple solutions, is there some package I could install (e.g. a completion package from Homebrew or the like) that would facilitate better tab-completion with any of these commands?
Looks to me like this is some incorrect scping.
This is the format of the command
scp ./localFile.txt remoteUser#remoteHost:/remoteFile.txt
You were so close, but you have localhost set where you should have your remoteHost.
localhost is the name that resolves to the machine that you are currently on - so in your workflow, you are sshing to a machine, and then trying to scp that file to the same machine you are already sshd into.
What you need to do, is figure out the IP address, or the physical host name of the computer that you are trying to connect to, and use that instead.
scp ./localFile.txt remoteUser#192.168.1.100:/remoteFile.txt
# where 192.168.1.100 would be the IP of your Mac
I am assuming the reason you were getting permission denied, was because you were using your the login credentials for you mac, but unknowingly trying to login again to your headless machine.

How to include a sub-script in a remote shell from remote location?

I am running a local bootstrap.sh script from OSX on a remote Ubuntu server which does some "if else then" stuff to load a specific subscript.sh when a specific condition is met.
I am running that local script with:
ssh user#host "bash -s" <~/projects/projectname/bootstrap.sh
I am having issues with getting the subscript.sh sourced (loaded/included).
You can't. You're only sending the contents of bootstrap.sh to the remote shell. It's attempting to source subscript.sh on the remote machine, and it isn't there.
You'll need to either copy subscript.sh (or both scripts!) to the remote machine, or insert the contents of subscript.sh into bootstrap.sh in place of the source command.
What I would recommend is to rsync your 'bootstrap.sh' from your local computer to your server. You should be able to do this with your ssh credentials.
A very cool utility is Transmit. It is $25 and allows you to cleanly mount your server as if it were a portable hard drive (Transmit can also do synchronizations). All you need is ssh credentials and is very user friendly.
If you are allowed to install on your server, then I would install qsub on it. (Actually just check to see if it is installed.) Then just mount your computer's drive and you can submit scrips with qsub (I actually would just make a small server on your mac). This is what I use for using a linux cluster from my OSX computer.
Alternatively you can make a small server from your osx and have it mounted on your linux server.

How can I automate running commands remotely over SSH to multiple servers in parallel?

I've searched around a bit for similar questions, but other than running one command or perhaps a few command with items such as:
ssh user#host -t sudo su -
However, what if I essentially need to run a script on (let's say) 15 servers at once. Is this doable in bash? In a perfect world I need to avoid installing applications if at all possible to pull this off. For argument's sake, let's just say that I need to do the following across 10 hosts:
Deploy a new Tomcat container
Deploy an application in the container, and configure it
Configure an Apache vhost
Reload Apache
I have a script that does all of that, but it relies on me logging into all the servers, pulling a script down from a repo, and then running it. If this isn't doable in bash, what alternatives do you suggest? Do I need a bigger hammer, such as Perl (Python might be preferred since I can guarantee Python is on all boxes in a RHEL environment thanks to yum/up2date)? If anyone can point to me to any useful information it'd be greatly appreciated, especially if it's doable in bash. I'll settle for Perl or Python, but I just don't know those as well (working on that). Thanks!
You can run a local script as shown by che and Yang, and/or you can use a Here document:
ssh root#server /bin/sh <<\EOF
wget http://server/warfile # Could use NFS here
cp app.war /location
command 1
command 2
/etc/init.d/httpd restart
EOF
Often, I'll just use the original Tcl version of Expect. You only need to have that on the local machine. If I'm inside a program using Perl, I do this with Net::SSH::Expect. Other languages have similar "expect" tools.
The issue of how to run commands on many servers at once came up on a Perl mailing list the other day and I'll give the same recommendation I gave there, which is to use gsh:
http://outflux.net/unix/software/gsh
gsh is similar to the "for box in box1_name box2_name box3_name" solution already given but I find gsh to be more convenient. You set up a /etc/ghosts file containing your servers in groups such as web, db, RHEL4, x86_64, or whatever (man ghosts) then you use that group when you call gsh.
[pdurbin#beamish ~]$ gsh web "cat /etc/redhat-release; uname -r"
www-2.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-2.foo.com: 2.6.9-78.0.1.ELsmp
www-3.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-3.foo.com: 2.6.9-78.0.1.ELsmp
www-4.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-4.foo.com: 2.6.18-92.1.13.el5
www-5.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-5.foo.com: 2.6.18-92.1.13.el5
[pdurbin#beamish ~]$
You can also combine or split ghost groups, using web+db or web-RHEL4, for example.
I'll also mention that while I have never used shmux, its website contains a list of software (including gsh) that lets you run commands on many servers at once. Capistrano has already been mentioned and (from what I understand) could be on that list as well.
Take a look at Expect (man expect)
I've accomplished similar tasks in the past using Expect.
You can pipe the local script to the remote server and execute it with one command:
ssh -t user#host 'sh' < path_to_script
This can be further automated by using public key authentication and wrapping with scripts to perform parallel execution.
You can try paramiko. It's a pure-python ssh client. You can program your ssh sessions. Nothing to install on remote machines.
See this great article on how to use it.
To give you the structure, without actual code.
Use scp to copy your install/setup script to the target box.
Use ssh to invoke your script on the remote box.
pssh may be interesting since, unlike most solutions mentioned here, the commands are run in parallel.
(For my own use, I wrote a simpler small script very similar to GavinCattell's one, it is documented here - in french).
Have you looked at things like Puppet or Cfengine. They can do what you want and probably much more.
For those that stumble across this question, I'll include an answer that uses Fabric, which solves exactly the problem described above: Running arbitrary commands on multiple hosts over ssh.
Once fabric is installed, you'd create a fabfile.py, and implement tasks that can be run on your remote hosts. For example, a task to Reload Apache might look like this:
from fabric.api import env, run
env.hosts = ['host1#example.com', 'host2#example.com']
def reload():
""" Reload Apache """
run("sudo /etc/init.d/apache2 reload")
Then, on your local machine, run fab reload and the sudo /etc/init.d/apache2 reload command would get run on all the hosts specified in env.hosts.
You can do it the same way you did before, just script it instead of doing it manually. The following code remotes to machine named 'loca' and runs two commands there. What you need to do is simply insert commands you want to run there.
che#ovecka ~ $ ssh loca 'uname -a; echo something_else'
Linux loca 2.6.25.9 #1 (blahblahblah)
something_else
Then, to iterate through all the machines, do something like:
for box in box1_name box2_name box3_name
do
ssh $box 'commmands_to_run_everywhere'
done
In order to make this ssh thing work without entering passwords all the time, you'll need to set up key authentication. You can read about it at IBM developerworks.
You can run the same command on several servers at once with a tool like cluster ssh. The link is to a discussion of cluster ssh on the Debian package of the day blog.
Well, for step 1 and 2 isn't there a tomcat manager web interface; you could script that with curl or zsh with the libwww plug in.
For SSH you're looking to:
1) not get prompted for a password (use keys)
2) pass the command(s) on SSH's commandline, this is similar to rsh in a trusted network.
Other posts have shown you what to do, and I'd probably use sh too but I'd be tempted to use perl like ssh tomcatuser#server perl -e 'do-everything-on-one-line;' or you could do this:
either scp the_package.tbz tomcatuser#server:the_place/.
ssh tomcatuser#server /bin/sh <<\EOF
define stuff like TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz or rsync rsync://repository/the_package_place
mv $TOMCAT_WEBAPPS/old_war $TOMCAT_WEBAPPS/old_war.old
mv $THE_PLACE/new_war $TOMCAT_WEBAPPS/new_war
touch $TOMCAT_WEBAPPS/new_war [you don't normally have to restart tomcat]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart [might need to login as apache user to move that file and restart]
EOF
You want DSH or distributed shell, which is used in clusters a lot. Here is the link: dsh
You basically have node groups (a file with lists of nodes in them) and you specify which node group you wish to run commands on then you would use dsh, like you would ssh to run commands on them.
dsh -a /path/to/some/command/or/script
It will run the command on all the machines at the same time and return the output prefixed with the hostname. The command or script has to be present on the system, so a shared NFS directory can be useful for these sorts of things.
Creates hostname ssh command of all machines accessed.
by Quierati
http://pastebin.com/pddEQWq2
#Use in .bashrc
#Use "HashKnownHosts no" in ~/.ssh/config or /etc/ssh/ssh_config
# If known_hosts is encrypted and delete known_hosts
[ ! -d ~/bin ] && mkdir ~/bin
for host in `cut -d, -f1 ~/.ssh/known_hosts|cut -f1 -d " "`;
do
[ ! -s ~/bin/$host ] && echo ssh $host '$*' > ~/bin/$host
done
[ -d ~/bin ] && chmod -R 700 ~/bin
export PATH=$PATH:~/bin
Ex Execute:
$for i in hostname{1..10}; do $i who;done
There is a tool called FLATT (FLexible Automation and Troubleshooting Tool) that allows you to execute scripts on multiple Unix/Linux hosts with a click of a button. It is a desktop GUI app that runs on Mac and Windows but there is also a command line java client.
You can create batch jobs and reuse on multiple hosts.
Requires Java 1.6 or higher.
Although it's a complex topic, I can highly recommend Capistrano.
I'm not sure if this method will work for everything that you want, but you can try something like this:
$ cat your_script.sh | ssh your_host bash
Which will run the script (which resides locally) on the remote server.
Just read a new blog using setsid without any further installation/configuration besides the mainstream kernel. Tested/Verified under Ubuntu14.04.
While the author has a very clear explanation and sample code as well, here's the magic part for a quick glance:
#----------------------------------------------------------------------
# Create a temp script to echo the SSH password, used by SSH_ASKPASS
#----------------------------------------------------------------------
SSH_ASKPASS_SCRIPT=/tmp/ssh-askpass-script
cat > ${SSH_ASKPASS_SCRIPT} <<EOL
#!/bin/bash
echo "${PASS}"
EOL
chmod u+x ${SSH_ASKPASS_SCRIPT}
# Tell SSH to read in the output of the provided script as the password.
# We still have to use setsid to eliminate access to a terminal and thus avoid
# it ignoring this and asking for a password.
export SSH_ASKPASS=${SSH_ASKPASS_SCRIPT}
......
......
# Log in to the remote server and run the above command.
# The use of setsid is a part of the machinations to stop ssh
# prompting for a password.
setsid ssh ${SSH_OPTIONS} ${USER}#${SERVER} "ls -rlt"
Easiest way I found without installing or configuring much software is using plain old tmux. Say you have 9 linux servers. Pick a box as your main. Start a tmux session:
tmux
Then create 9 split tmux panes by doing this 8 times:
ctrl-b + %
Now SSH into each box in each pane. You'll need to know some tmux shortcuts. To navigate, press:
ctrl+b <arrow-keys>
Once your logged in to all your boxes on each pane. Now turn on pane synchronization where it lets you type the same thing into each box:
ctrl+b :setw synchronize-panes on
now when you press any keys, it will show up on every pane. to turn it off, just make on to off. to cycle resize panes, press ctrl+b < space-bar >.
This works alot better for me since I need to see each terminal output as sometimes servers crash or hang for whatever reason when downloading or upgrade software. Any issues, you can just isolate and resolve individually.

Resources