Обработка массива команд git внутри скрипта bash - PullRequest
0 голосов
/ 26 декабря 2018

Добрый день всем:

Я пишу bash-скрипт для извлечения данных из git-репозиториев.У меня есть массив для хранения имен репозитория:

declare -a arr=(
https://"$USER"@stash/repo1.git
https://"$USER"@stash/rep2.git
)

Я обрабатываю его следующим образом:

for i in "${arr[@]}"
do
    git clone "$i"
    ......
    git install
done

Это работает.Теперь я хочу иметь возможность опционально указать ветку git:

declare -a arr=(
    -b branch1 --single-branch https://"$USER"@stash/repo1.git
    https://"$USER"@stash/rep2.git
)

Сценарий обработки массива завершается с ошибками: - ключ `b 'требует значения - недопустимый идентификатор и т. Д.

Каков правильный и простой подход, чтобы заставить его работать?

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Может быть, это сработает, если вы удалите кавычки вокруг

git clone "$i"

Так это будет выглядеть так:

git clone $i

Я думаю, что оболочка с кавычками должна рассматривать всю вашу строку как однуодин аргумент вместо многих:

git clone "-b branch1 --single-branch https://"$USER"@stash/repo1.git"

Это выглядит неправильно.

РЕДАКТИРОВАТЬ: @CharlesDuffy указал на другую проблему, которую я пропустил: вы также должны иметь кавычки вокруг всей строки в определении массива (но это не сработает, если вам действительно нужны внутренние кавычки вокруг $USER, см. пример ниже):

declare -a arr=(
    "-b branch1 --single-branch https://$USER@stash/repo1.git"
    https://"$USER"@stash/rep2.git
)

Я проверил это на своей локальной машине, и, похоже, это работает.

$ ls
one/  test.sh*

$ ( cd one/ ; git branch )
* another_branch
  master

$ cat test.sh
#!/bin/bash

declare -a arr=(
"-b another_branch --single-branch one two"
)

for i in "${arr[@]}"
do
        git clone $i
done

$ ls
one/  test.sh*

$ ./test.sh
Cloning into 'two'...
done.

$ ls
one/  test.sh*  two/

$ ( cd two/ ; git branch )
* another_branch

$

РЕДАКТИРОВАТЬ 2: Это будет работать, только если вы можете безопасно пропустить внутренние кавычки вокруг $USER.Если они вам нужны, вы должны использовать eval внутри цикла for, а также заключать в кавычки внутренние кавычки в объявлении массива.

$ cat ./test.sh
#!/bin/bash

USER="username containing spaces"   # just for example!

git () {
        echo "$5"
}

declare -a arr=(
"-b branch1 --single-branch https://\"$USER\"@stash/repo1.git"
)

for i in "${arr[@]}"
do
        printf "without eval:\t"
        git clone $i
        printf "with eval:\t"
        eval "git clone $i"
done


$ ./test.sh
without eval:   https://"username
with eval:      https://username containing spaces@stash/repo1.git

Это еще одна ошибка, которую @CharlesDuffy обнаружил в моем ответе.Спасибо, Чарльз, я многому учусь, углубляясь в проблемы, на которые ты указал!

0 голосов
/ 26 декабря 2018

ср printf "%s\n" "${arr[@]}".То, что эти аргументы находятся в одной строке, не делает их одним элементом.:)

Вы пытаетесь сделать две вещи с одним массивом.

Попробуйте это -

declare -a arr=(
   "https://$USER@stash/repo1.git#branch1"
   "https://$USER@stash/rep2.git"
)

for i in "${arr[@]}"
do  IFS='#' read url branch <<< "$i"
    if [[ -n "$branch" ]]
    then git clone -b "$branch" --single-branch "$url"
    else git clone "$url"
    :    ......
    git install
done

Предупреждение - нет шансов проверить это. Caveat Scriptor - и, конечно, это означает, что # нигде не может быть в вашем url.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...