Bash scripting, git and filenames with spaces

I am trying to automate some of my interactions with git using bash scripts. To do so I have a script that will ssh and list all the repositories and then clone them. Part of the script is shown here

DIRS=`ssh $u "ls $p"`;
for DIR in $DIRS; do
    echo "ssh://$u$p$DIR"
    echo "git clone ssh://$u$p$DIR";  
    git clone ssh://$u$p$DIR
done

Example arguments are

-u user@host

and

-p /cygdrive/c/Documents\ and\ Settings/somePath

This work fine for filepaths with spaces in their names up until the git clone part where it throws an error about too many spaces. If I copy and pasted the part echoed by

echo "git clone ssh://$u$p$DIR";

then it clones just fine. I have tried to surround this in quotes but it throws an error

does not appear to be a git repository

What am I doing wrong?

Edit 1

The errors when using git clone "ssh://$u$p$DIR" is

fatal: '/cygdrive/c/Documents\ and\ Settings/somePath/repo1' does not appear to be a git repository
fatal: The remote end hung up unexpectedly

Answers


If your directory names contain spaces, you most certainly don't want to be doing this:

DIRS=`ssh $u "ls $p"`;
for DIR in $DIRS; do

Since you want to preserve your spaces instead of consuming them as delimiters, the generally accepted way of doing this is telling bash that delimiters are line-feeds:

IFS=$'\n'
for DIR in `ssh $u "ls -1 $p"`; do

If you really must have your variable DIRS, you can use bash's array variables (which will preserve your spaces):

IFS=$'\n'
DIRS=(`ssh $u "ls -1 $p"`)
unset IFS
for DIR in "${DIRS[@]}"; do

Another general form is using read:

ssh $u "ls -1 $p" | while read DIR; do

Or:

while read DIR; do
    ...
done < <(ssh $u "ls -1 $p")

However, these aren't recommended as error handling (especially on ssh becomes a bit more involved when you start using pipes.)

Everything up to this point is just basic bash scripting.

As for this line, you'd want to enclose the second argument with double-quotes because a space in $DIR will make a 3rd argument out of it:

git clone "ssh://$u$p$DIR"

I tried this in git and it seems to work. However as @holygeek said, replacing the spaces with %20 also seems to work, and might beneficial in certain cases. You can do this like so:

git clone "ssh://$u$p${DIR// /%20}"

Need Your Help

SSIS Lookup component failed to process the rows in the cache

sql-server ssis lookup etl

I'm working with SQL Server 2008 R2 Integration Services. I have an etl process with a Lookup component, that was working just fine. I made some changes to data sources, but the amount of data is l...

C++ function specialization for equal parameters

c++ templates matrix overloading template-specialization

I, like so many others, am writing a linear algebra library for my personal use. In doing so, I'm trying to learn more about programming with templates in C++. I have a class, which goes something ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.