Как клонировать сразу все репозитории с GitHub?


97

У меня есть корпоративная учетная запись GitHub, и я хочу создать резервную копию всех репозиториев в ней, учитывая все новое, что может быть создано в целях автоматизации. Я надеялся примерно так:

git clone git@github.com:company/*.git 

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

Есть ли способ в Git клонировать, а затем извлекать все, если у вас есть соответствующие разрешения?


2
Хороший вопрос. А как насчет того, чтобы синхронизировать их с помощью pull? Какие-нибудь ответы работают на тяги?
nealmcb

Нам нужно решение на Python, для тех из нас, кто не слишком разбирается в node или ruby;) Или github должен прочитать это и сжалиться над нами и просто предоставить для этого простой веб-интерфейс ...
nealmcb

Попробуйте: github.com/wballard/git-friends
kenorb

Ответы:


52

Я не думаю, что это возможно. Лучше всего найти и просмотреть список репозиториев Организации с помощью API.

Попробуй это:

  • Создайте токен API, перейдя в Настройки учетной записи -> Приложения.
  • Позвоните: http://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}
  • Ответом будет массив объектов JSON. Каждый объект будет включать информацию об одном из репозиториев данной Организации. Думаю, в вашем случае вы будете искать именно эту ssh_urlнедвижимость.
  • Тогда git cloneкаждый из этих ssh_urls.

Это немного лишняя работа, но для GitHub необходимо иметь правильную аутентификацию.


Я создал токен API и получаю результат вызова, но я не вижу ничего, ссылающегося на то, что я знаю о наших репозиториях или строке ssh_url. Подозреваю, что позвонил неправильно. curl -i https://github.com/api/v3/orgs/company/repos?access_token=<token>
numb3rs1x

Это учетная запись GitHub Enterprise или github.com?
Томас Келли,

1
Ах, я вас неправильно понял. Я думал, что это была учетная запись Enterprise. Вместо того https://github.com/api/v3/, чтобы попробовать https://api.github.com/.
Томас Келли,

1
И я не уверен, как устроена ваша конкретная компания, но если это «пользователь», а не «организация», тогда вы захотите использовать /users/${COMPANY}/reposпуть вместо /orgs/${COMPANY}/repos.
Томас Келли,

1
На GitHub: используйте вместо него HTTP-заголовок авторизации, поскольку использование access_tokenпараметра запроса устарело. Если этот токен используется приложением, которое вы не контролируете, имейте в виду, что оно может перестать работать в результате этого устаревания.
BogeyMan,

114

В Windows и всех системах UNIX / LINUX , используя Git Bash или любой другой Терминал , замените YOURUSERNAMEсвое имя пользователя и используйте:

CNTX={users|orgs}; NAME={username|orgname}; PAGE=1
curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" |
  grep -e 'git_url*' |
  cut -d \" -f 4 |
  xargs -L1 git clone
  • Установите CNTX=usersи NAME=yourusername, чтобы загрузить все ваши репозитории.
  • Установите CNTX=orgsи NAME=yourorgname, чтобы загрузить все репозитории вашей организации.

Максимальный размер страницы - 100, поэтому вам придется вызывать его несколько раз с правильным номером страницы, чтобы получить все ваши репозитории (установите PAGEжелаемый номер страницы, которую вы хотите загрузить).

Вот сценарий оболочки, который выполняет вышеуказанное: https://gist.github.com/erdincay/4f1d2e092c50e78ae1ffa39d13fa404e


4
Чистое решение на bash, самое простое. К вашему сведению, этот код bash может быть выполнен практически в любой среде * nix, Linux, Cygwin, Mingw и, конечно же, Gitbash, который на самом деле является эмуляцией терминала, как и другие.
m3nda

1
Это не работает с организациями, поэтому не дает прямого ответа на вопрос. Этот ответ от Kenorb действительно обрабатывает организации и работает до 1000 репозиториев - для меня сработал лучше.
RichVel

1
с аутентификацией: curl " api.github.com/$CNTX/$NAME/… " | grep -e 'git_url *' | cut -d \ "-f 4 | xargs -L1 git clone
Янник Вурм

2
Обновите ответ (февраль 2019 г.): согласно GitHub API v3 ваш curl должен идти в / orgs / ORGNAME / repos. Также можно включить ссылку на API v3: developer.github.com/v3. Также для частных репозиториев вам нужно будет добавить curl -u «имя пользователя», тогда curl один раз спросит у вас пароль. В остальном работает отлично!
Дмитрий Шевкопляс

1
ОБНОВЛЕНИЕ от димитрия хевкопляс комментарий stackoverflow.com/questions/19576742/… . developer.github.com/v3 возвращает статус 301 при попытке свернуть. используйте эту команду bash curl -u "{username}" " api.github.com/orgs {org} / repos? page = 1 & per_page = 100" | grep -o 'git @ [^ "] *' | xargs -L1 git clone работает на 100%
Томми

44

Репозитории организации

Чтобы клонировать все репозитории вашей организации, попробуйте следующую однострочную оболочку:

GHORG=company; curl "https://api.github.com/orgs/$GHORG/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone

Репозитории пользователей

Клонирование всего с использованием URL-адресов репозитория Git:

GHUSER=CHANGEME; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone

Клонирование всего с помощью Clone URL:

GHUSER=CHANGEME; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -w clone_url | grep -o '[^"]\+://.\+.git' | xargs -L1 git clone

Вот полезная функция оболочки, которую можно добавить в файлы запуска пользователя (используя curl+ jq):

# Usage: gh-clone-user (user)
gh-clone-user() {
  curl -sL "https://api.github.com/users/$1/repos?per_page=1000" | jq -r '.[]|.clone_url' | xargs -L1 git clone
}

Частные репозитории

Если вам нужно клонировать частные репозитории, вы можете добавить токен авторизации в свой заголовок, например:

-H 'Authorization: token <token>'

или передайте его в param ( ?access_token=TOKEN), например:

curl -s "https://api.github.com/users/$GHUSER/repos?access_token=$GITHUB_API_TOKEN&per_page=1000" | grep -w clone_url | grep -o '[^"]\+://.\+.git' | xargs -L1 git clone

Ноты:

  • Чтобы получить только частные репозитории, добавьте type=privateв строку запроса.
  • Другой способ - использовать hubпосле настройки ключа API.

Смотрите также:


Подсказки :
- Для увеличения скорости установите количество параллельных процессов, указав -Pпараметр для xargs( -P4= 4 процесса).
- Если вам нужно поднять ограничения GitHub, попробуйте выполнить аутентификацию, указав свой ключ API.
- Добавить --recursiveрекурсию в зарегистрированные подмодули и обновить все вложенные подмодули внутри.


2
per_page = 1000 максимумов при 100
aehlke

20

Эта суть выполняет задачу в одной строке командной строки:

curl -s https://api.github.com/orgs/[your_org]/repos?per_page=200 | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'

Замените [your_org]названием своей организации. И установите свойper_page при необходимости .

ОБНОВИТЬ:

Как упоминалось в ATutorMe, максимальный размер страницы составляет 100, согласно документации GitHub .

Если у вас более 100 репозиториев, вам нужно будет добавить pageпараметр в свой URL-адрес, и вы можете запустить команду для каждой страницы.

curl -s "https://api.github.com/orgs/[your_org]/repos?page=2&per_page=100" | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'

Примечание. Параметр по умолчанию per_page- 30.


Есть идеи, как это делается для частных репозиториев, к которым у вас есть доступ?
MichaelGofron

второй не работает, потому что амперсанд заставляет его перейти в фоновую задачу
slashdottir

Я добавил & access_token = <my_access_token> к URL-адресу, и он работал отлично
rmartinus

2-й: page = 1 (!)
Янник Вурм

5

Перейдите в Настройки учетной записи -> Приложение и создайте ключ API.
Затем вставьте ключ API, URL-адрес экземпляра github и название организации в сценарий ниже.

#!/bin/bash

# Substitute variables here
ORG_NAME="<ORG NAME>"
ACCESS_TOKEN="<API KEY>"
GITHUB_INSTANCE="<GITHUB INSTANCE>

URL="https://${GITHUB_INSTANCE}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}"

curl ${URL} | ruby -rjson -e 'JSON.load(STDIN.read).each {|repo| %x[git clone #{repo["ssh_url"]} ]}'

Сохраните это в файл, chmod u+xфайл, затем запустите.

Спасибо Арно за рубиновый код.


5

Так что я тоже добавлю свой ответ. :) (я нашел это просто)

Список выборки (я использовал компанию "magento"):

curl -si https://api.github.com/users/magento/repos | grep ssh_url | cut -d '"' -f4

Используйте clone_urlвместоssh_url доступа использовать HTTP.

Итак, давайте клонируем их все! :)

curl -si https://api.github.com/users/magento/repos | \
    grep ssh_url | cut -d '"' -f4 | xargs -i git clone {}

Если вы собираетесь получить частное репо - просто добавьте параметр GET ?access_token=YOURTOKEN


4

Я обнаружил, что комментарий в gist @seancdavis очень полезен, особенно потому, что, как и исходный плакат, я хотел синхронизировать все репозитории для быстрого доступа, однако подавляющее большинство из них были частными.

curl -u [[USERNAME]] -s https://api.github.com/orgs/[[ORGANIZATION]]/repos?per_page=200 |
  ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'

Замените [[USERNAME]] своим именем пользователя github, а [[ORGANIZATION]] - своей организацией Github. Вывод (метаданные репозитория JSON) будет передан простому скрипту ruby:

# bring in the Ruby json library
require "json"

# read from STDIN, parse into ruby Hash and iterate over each repo
JSON.load(STDIN.read).each do |repo|
  # run a system command (re: "%x") of the style "git clone <ssh_url>"
  %x[git clone #{repo["ssh_url"]} ]
end

1
Это решение отлично сработало для меня. На самом деле все, что мне нужно, - это клонировать все репозитории моей личной учетной записи на мою новую локальную машину. Очень удобно для установки новой рабочей станции. Примечание: для этого мне пришлось перейти .../orgs/[[organization]]/repos...на .../users/[[username]]/repos.... Теперь я могу быстро импортировать всю свою работу на разные локальные машины. СПАСИБО!
Б. Булпетт,


2

Этот однострочный файл python сделает то, что вам нужно. Это:

  • проверяет github на наличие доступных репозиториев
  • для каждого делает системный вызов git clone

    python -c "import json, urllib, os; [os.system('git clone ' + r['ssh_url']) for r in json.load(urllib.urlopen('https://api.github.com/orgs/<<ORG_NAME>>/repos?per_page=200'))]"
    

2
curl -s https://api.github.com/orgs/[GITHUBORG_NAME]/repos | grep clone_url | awk -F '":' '{ print $2 }' | sed 's/\"//g' | sed 's/,//' | while read line; do git clone "$line"; done

2
Пожалуйста, добавьте пояснение к своему решению. Таким образом, другие люди с подобными проблемами смогут легче понять ваше решение!
Нандер Спирстра

Деталь, нужно передать номер страницы как ?page=2.
Бруно

2

Простое решение:

NUM_REPOS=1000
DW_FOLDER="Github_${NUM_REPOS}_repos"
mkdir ${DW_FOLDER}
cd ${DW_FOLDER}
for REPO in $(curl https://api.github.com/users/${GITHUB_USER}/repos?per_page=${NUM_REPOS} | awk '/ssh_url/{print $2}' | sed 's/^"//g' | sed 's/",$//g') ; do git clone ${REPO} ; done

2

Я попробовал несколько команд и инструментов, описанных выше, но решил, что они доставляют слишком много хлопот, поэтому я написал для этого еще один инструмент командной строки, названный github-dl.

Чтобы использовать его (при условии, что у вас установлен nodejs)

npx github-dl -d /tmp/test wires

Это позволит получить список всех репозиториев wiresи записать информацию в testкаталог, используя данные авторизации (пользователь / пароль), которые вы указываете в CLI.

В частности, это

  1. Запрашивает авторизацию (поддерживает 2FA)
  2. Получает список репозиториев для пользователя / организации через Github API
  3. Обеспечивает разбиение на страницы для этого, поэтому поддерживается более 100 репо

На самом деле он не клонирует репозитории, а вместо этого записывает .txtфайл, в который вы можете перейти xargsдля клонирования, например:

cd /tmp/test
cat wires-repo-urls.txt | xargs -n2 git clone

# or to pull
cat /tmp/test/wires-repo-urls.txt | xargs -n2 git pull

Может быть, это будет полезно для вас; это всего лишь несколько строк JS, поэтому их будет легко приспособить к вашим потребностям.


1

Для этого также есть очень полезный модуль npm . Он может не только клонировать, но и извлекать (обновлять данные, которые у вас уже есть).

Вы просто создаете такую ​​конфигурацию:

[{
   "username": "BoyCook",
   "dir": "/Users/boycook/code/boycook",
   "protocol": "ssh"
}]

и сделай gitall cloneнапример. Илиgitall pull


1

В случае, если кто-то ищет решение для Windows, вот небольшая функция в PowerShell, чтобы сделать трюк (может быть один лайнер / псевдоним, если не тот факт, что он мне нужен для работы как с прокси, так и без него).

function Unj-GitCloneAllBy($User, $Proxy = $null) {
    (curl -Proxy $Proxy "https://api.github.com/users/$User/repos?page=1&per_page=100").Content 
      | ConvertFrom-Json 
      | %{ $_.clone_url } 
      # workaround git printing to stderr by @wekempf aka William Kempf
      # https://github.com/dahlbyk/posh-git/issues/109#issuecomment-21638678
      | %{ & git clone $_ 2>&1 } 
      | % { $_.ToString() }
}

1

Таким образом, на практике, если вы хотите клонировать все операции РЕПО из организации , FOOкоторые соответствуют BAR, вы можете использовать одну гильзу ниже, что требует JQ и общих утилит Cli

curl 'https://api.github.com/orgs/FOO/repos?access_token=SECRET' |
  jq '.[] |
  .ssh_url' |
  awk '/BAR/ {print "git clone " $0 " & "}' |
  sh

1

Другой сценарий оболочки с комментариями, который клонирует все репозитории (публичные и частные) от пользователя:

#!/bin/bash

USERNAME=INSERT_USERNAME_HERE
PASSWORD=INSERT_PASSWORD_HERE

# Generate auth header
AUTH=$(echo -n $USERNAME:$PASSWORD | base64)

# Get repository URLs
curl -iH "Authorization: Basic "$AUTH https://api.github.com/user/repos | grep -w clone_url > repos.txt

# Clean URLs (remove " and ,) and print only the second column
cat repos.txt | tr -d \"\, | awk '{print $2}'  > repos_clean.txt

# Insert username:password after protocol:// to generate clone URLs
cat repos_clean.txt |  sed "s/:\/\/git/:\/\/$USERNAME\:$PASSWORD\@git/g" > repos_clone.txt

while read FILE; do
    git clone $FILE
done <repos_clone.txt

rm repos.txt & rm repos_clone.txt

1

Создайте псевдоним / func для bash в своем ~/.bashrc file

Я решил это для своей команды, создав псевдоним / bash func в моем ~/.bashrc file

шаги

откройте терминал или оболочку Linux и откройте ~/.bashrc file:

sudo nano ~/.bashrc

добавить эту функцию:

CloneAll() {
    # Make the url to the input github organization's repository page.
    ORG_URL="https://api.github.com/orgs/${1}/repos?per_page=200";

    # List of all repositories of that organization (seperated by newline-eol).
    ALL_REPOS=$(curl -s ${ORG_URL} | grep html_url | awk 'NR%2 == 0' \
                | cut -d ':' -f 2-3 | tr -d '",');

    # Clone all the repositories.
    for ORG_REPO in ${ALL_REPOS}; do
        git clone ${ORG_REPO}.git;
    done
}

сохраните и закройте файл ~ / .bashrc, а затем закройте терминал - вам нужно сделать это, иначе новая функция не инициализируется:

откройте новый терминал и попробуйте:

CloneAll <your_github_org_name>

пример : если ваш личный URL-адрес репозитория github называется https://github.com/awesome-async, команда будет

CloneAll awesome-async

Важный

per_page=200в конце первой переменной ORG_URLзадает число операций РЕПО , которые будут клонированы, поэтому обратите особое внимание , что:

ORG_URL="https://api.github.com/orgs/${1}/repos?per_page=200";  <---- make sure this is what you want

Надеюсь это поможет! :)


Кажется макс. значение для per_page равно 100 ... для крупных организаций добавлен номер страницы в качестве второго параметра, и он отлично работает для моих нужд...repos?page=${2}&per_page=100";
sv3n

0

Вы можете получить список репозиториев, используя, curlа затем перебрать указанный список с помощью цикла bash:

GIT_REPOS=`curl -s curl https://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN} | grep ssh_url | awk -F': ' '{print $2}' | sed -e 's/",//g' | sed -e 's/"//g'`
for REPO in $GIT_REPOS; do
  git clone $REPO
done

0

Вы можете использовать инструмент с открытым исходным кодом для клонирования нескольких репозиториев github: https://github.com/artiomn/git_cloner

Пример:

git_cloner --type github --owner octocat --login user --password user https://my_bitbucket

Используйте JSON API из api.github.com. Вы можете увидеть пример кода в документации github: https://developer.github.com/v3/

Или там:

https://github.com/artiomn/git_cloner/blob/master/src/git_cloner/github.py


0

Чтобы клонировать только частные репозитории с учетом ключа доступа и установленного модуля python 3 и запросов:

ORG=company; ACCESS_KEY=0000000000000000000000000000000000000000; for i in $(python -c "import requests; print(' '.join([x['ssh_url'] for x in list(filter(lambda x: x['private'] ,requests.get('https://api.github.com/orgs/$ORG/repos?per_page=1000&access_token=$ACCESS_KEY').json()))]))"); do git clone $i; done;

0

Решение Python3, которое включает исчерпывающую разбивку на страницы через Link заголовок.

Предварительные условия:


import json
import requests
from requests.auth import HTTPBasicAuth
import links_from_header

respget = lambda url: requests.get(url, auth=HTTPBasicAuth('githubusername', 'githubtoken'))

myorgname = 'abc'
nexturl = f"https://api.github.com/orgs/{myorgname}/repos?per_page=100"

while nexturl:
    print(nexturl)
    resp = respget(nexturl)

    linkheads = resp.headers.get('Link', None)
    if linkheads:
        linkheads_parsed = links_from_header.extract(linkheads)
        nexturl = linkheads_parsed.get('next', None)
    else:
        nexturl = None

    respcon = json.loads(resp.content)
    with open('repolist', 'a') as fh:
        fh.writelines([f'{respconi["full_name"]}\n' for respconi in respcon])

Затем вы можете использовать xargsили параллельно и:cat repolist | parallel -I% hub clone %


0

Если у вас есть список репозиториев в виде такого списка, то этот сценарий оболочки работает:

user="https://github.com/user/"

declare -a arr=("repo1", "repo2")

for i in "${arr[@]}"

do

   echo $user"$i"

   git clone $user"$i"

done 

если есть какие-то частные репозитории, вы можете обновить "user" следующим образом: user = " user: password@github.com/user "
Мед Али Дифаллах

0

Я создал образец пакетного сценария. Вы можете скачать все частные / общедоступные репозитории с github.com. После загрузки репозиторий он автоматически преобразуется в zip-файл.

@echo off
setlocal EnableDelayedExpansion
SET "username=olyanren"
SET "password=G....."
set "mypath=%cd%\"
SET "url=https://%username%:%password%@github.com/%username%/"
FOR /F "tokens=* delims=" %%i in (files.txt) do (
SET repo=%%i
rmdir /s /q !repo!
git clone "!url!!repo!.git"
cd !repo!
echo !mypath!
git archive --format=zip -o "!mypath!!repo!.zip" HEAD
cd ..
)

Примечание: файл files.txt должен содержать только имена репозитория, например:

repository1
repository2

0

Обновление от 19 мая

используйте эту команду bash для организации (включая частное репо)

curl -u "{username}" "https://api.github.com/orgs/{org}/repos?page=1&per_page=100" | grep -o 'git@[^"]*' | xargs -L1 git clone

0

Преобладающие ответы здесь не учитывают, что Github API вернет не более 100 репозиториев, несмотря на то, что вы можете указать в per_page. Если вы клонируете организацию Github с более чем 100 репозиториями, вам нужно будет перейти по ссылкам на страницы в ответе API.

Для этого я написал инструмент CLI :

clone-github-org -o myorg

Это клонирует все репозитории в myorgорганизации в текущий рабочий каталог.


0

Для организаций, к которым у вас есть доступ с частными репозиториями:

curl -u <YOUR_GITHUB_USERNAME> -s https://api.github.com/orgs/<ORG_NAME>/repos?per_page=200 | ruby -rubygems -e ’require “json”; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo[“html_url”]} ]}'

Он использует html_url, поэтому вам не нужно access_tokenпросто вводить свой пароль github при появлении запроса.


Обычная проверка подлинности с использованием пароля к API устарела и скоро перестанет работать. Посетите [deprecating-password-auth] ( developer.github.com/changes/… ) для получения дополнительной информации о предлагаемых обходных путях и датах удаления.
BogeyMan,

0

Клонируйте все ваши репозитории, не являющиеся форками:

curl -u "username" https://api.github.com/user/repos\?page\=1\&per_page\=100 |
  jq -r 'map(select(.fork == false)) | .[] | .ssh_url' |
  xargs -L1 git clone

Клонируйте свои сущности:

curl https://api.github.com/users/username/gists\?page\=1\&per_page\=100 |
   jq -r ".[] | .git_pull_url +\" '\" + (.files|keys|join(\"__\") + \"'\")" |
   xargs -L1 git clone

Эта jqкоманда сложна, потому что имя репозитория gists - это хэши, поэтому эта команда объединяет все имена файлов в имя репо.


Вы можете произвольно фильтровать JSON, используя jq

установить: sudo apt-get install jq

В приведенном выше примере я отфильтровал вилки, используя следующее: curl ... | jq -r 'map(select(.fork == false))' ...- полезно для того, чтобы не клонировать репозитории, в которых вы делали случайные запросы на вытягивание

jq поддерживает некоторые очень продвинутые функции. man jqтвой друг


Вы можете пройти аутентификацию с помощью curl -u "username" ... для доступа к частным репозиториям


URL-адреса API Guthub

  • Ваши репозитории (требуется аутентификация): https://api.github.com/user/repos\?page\=1\&per_page\=100
  • Любой пользователь: https://api.github.com/users/other_username/repos\?page\=1\&per_page\=100
  • Организации: https://api.github.com/orgs/orgname/repos\?page\=1\&per_page\=100

Документы Github API для репозиториев


0
"""
Clone all public Github Repos

https://developer.github.com/v3/repos/#list-repositories-for-a-user
"""

import urllib.request, base64
import json
import os


def get_urls(username):
    url = f"https://api.github.com/users/{username}/repos?per_page=200"
    request = urllib.request.Request(url)
    result = urllib.request.urlopen(request)
    return json.load(result)


if __name__ == "__main__":
    for r in get_urls("MartinThoma"):
        if not os.path.isdir(r["name"]):
            print(f"Clone {r['name']}...")
            os.system("git clone " + r["ssh_url"])
        else:
            print(f"SKIP {r['name']}...")

0

Чтобы клонировать все ваши собственные частные и общедоступные репозитории, просто создайте новый токен доступа с доступом к репозиториям и используйте его:

(замените свой токен доступа и имя пользователя)

for line in $(curl https://api.github.com/user/repos?access_token=ACCESS_TOKEN_HERE  | grep -o "git@github.com:YOUR_USER_NAME/[^ ,\"]\+");do git clone $line;done

Это клонирует все репозитории в текущей папке

Это небольшая программа на bash, вы можете просто вставить ее в терминал и нажать Enter.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.