Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash scripting, git and filenames with spaces

Tags:

git

bash

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
like image 815
Codey McCodeface Avatar asked Dec 22 '25 00:12

Codey McCodeface


1 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}"
like image 80
antak Avatar answered Dec 23 '25 18:12

antak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!