How do I create a directory on remote host if it doesn't exist without ssh-ing in?

BashScriptingScp

Bash Problem Overview


I'm not sure if this is possible or not. Basically, I'm writing a script that allows me to scp a file to my hosting. This is it so far. Argument 1 is the file and argument 2 is the folder I want it to be placed in on the remote server:

function upload {
    scp $1 [email protected]:$2
}

As you may/may not know, if the directory I specify when I call the function doesn't exist, then the transfer fails. Is there a way to check if the directory exists in the function and if it doesn't, create it.

I would prefer not having to ssh in every time and create the directory, but if I have got no choice, then I have got no choice.

Bash Solutions


Solution 1 - Bash

You can use rsync.

For example,

rsync -ave ssh fileToCopy ssh.myhost.net:/some/nonExisting/dirToCopyTO

Note about rsync:

rsync is utility software and network protocol for Unix which synchronizes files and directories from one location to another. It minimizes data transfer sizes by using delta encoding when appropriate using the rsync algorithm which is faster than other tools.

Solution 2 - Bash

I assume you mean you don't want to interactively log in and create directories by hand, rather than that you want to avoid using ssh altogether, since you still need a password or public key with scp.

If using ssh non-interactively is acceptable, then you can stream your file using cat over ssh:

cat $1 | ssh $2 "mkdir $3;cat >> $3/$1"

where

$1 = filename 
$2 = user@server
$3 = dir_on_server

If the directory already exists, mkdir complains but the file is still copied over. The existing directory will not be overwritten. If the directory does not exist, mkdir will create it.

Solution 3 - Bash

If you do a recursive scp (-r), it will copy directories as well. So if you create a directory of the name you desire on the remote host locally, copy the file into it, and then recursively copy, the directory will be created, with the file in it.

Kind of awkward, but it would do the job.

Solution 4 - Bash

This is a two step process

ssh [email protected] "mkdir -p $2"

This ensures directory structure is created. Then, you copy

scp $1 [email protected]:$2

Solution 5 - Bash

How about, for example,
ssh [email protected] '[ -d /tmp/nonexist/dir ] || mkdir -p /tmp/nonexist/dir ]'; scp test.txt [email protected]:/tmp/nonexist/dir

Solution 6 - Bash

sshfs be fancy!

Example .ssh/config

Host your-host
  HostHame example.com
  User name
  IdentitiesOnly yes
  IdentityFile ~/.ssh/private_key

Local setup aside from above only requires a target mount point...

sudo mkdir /media/your-host
sudo chown ${USER}:${USER} /media/your-host

... after which things like mounting and un-mounting are far simpler to script.

Mount

sshfs your-host:within-home/some-dir /media/your-host

Unmount

fusermount -u /media/your-host

The best part about this approach, when a server allows it, is that locally running scripts can interact with the remote file system. Meaning that things like...

if ! [ -d "/media/your-host/nowhere" ]; then
  mkdir -vp "/media/your-host/nowhere"
fi

... become possible among many other tricks that can be performed via such mounting magics.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlarjudgeView Question on Stackoverflow
Solution 1 - BashPeter MortensenView Answer on Stackoverflow
Solution 2 - Bashire_and_cursesView Answer on Stackoverflow
Solution 3 - BashMatthias WandelView Answer on Stackoverflow
Solution 4 - BashSarangView Answer on Stackoverflow
Solution 5 - BashRico ChenView Answer on Stackoverflow
Solution 6 - BashS0AndS0View Answer on Stackoverflow