diff --git a/archive/README.md b/archive/README.md index d776d95..05597ad 100644 --- a/archive/README.md +++ b/archive/README.md @@ -1,5 +1,5 @@ | Незавершённые публикации | Язык | Обновление | -|:-----------------------------------------------------------------|------|------------| -| [Распараллеливание скриптов Bash](parallelizing-bash-scripts.md) | Bash | 2024.08.15 | +|------------------------------------------------------------------|------|------------| +| [Распараллеливание скриптов Bash](parallelizing-bash-scripts.md) | Bash | 2024.09.05 | | [Циклический алгоритм распределения задач](round-robin.md) | Java | 2023.06.05 | diff --git a/archive/parallelizing-bash-scripts.md b/archive/parallelizing-bash-scripts.md index 11e6649..c4ddacb 100644 --- a/archive/parallelizing-bash-scripts.md +++ b/archive/parallelizing-bash-scripts.md @@ -1,13 +1,12 @@ # Распараллеливание скриптов Bash -Примером последовательности действий, не зависящих друг от друга, могут быть — итерации циклов, или вызовы функций с -параметрами. Когда цикл один, или функция одна — это тривиальная задача для распараллеливания. Рассмотрим усложнённую -модель с тремя функциями и тремя параметрами для каждой — будем распараллеливать вызовы этих функций. +Рассмотрим последовательность действий, не зависящих друг от друга — это итерации циклов, или вызовы функций с параметрами. +Когда цикл один, или функция одна — это тривиальная задача для распараллеливания. Рассмотрим усложнённую модель с тремя +функциями и тремя параметрами для каждой — будем распараллеливать вызовы этих функций с использованием программы `xargs`. -Сначала кодируем параметры в HEX коды и отбрасываем разделители строк — чтобы не заниматься экранированием спецсимволов. -Затем создаём массив строк — вызовы функций с параметрами. Далее выполняем эти строки в параллельном режиме с помощью -программы `xargs` — вызываем целевые функции командой `eval`. Внутри каждой функции сначала декодируем параметры -обратно и затем работаем с ними. Дополнительно для наглядности замеряем общее время выполнения функций. +Для решения вопроса об экранировании спецсимволов — сначала все параметры кодируем в HEX коды и после этого составляем с ними +строки — вызовы функций с параметрами. Далее обходим массив строк и выполняем функции в параллельном режиме. Внутри каждой из +них сначала декодируем параметры обратно и затем работаем с ними. Для наглядности замеряем общее время выполнения функций. ```bash #!/bin/bash @@ -41,10 +40,10 @@ function third_func { #---------------------------------------------------------------------------; # вспомогательные функции и экспорт для дочерних процессов #---------------------------------------------------------------------------; -# удаление разделителей строк и кодирование символов в HEX коды -function encode { echo "$1" | tr -d '\r\n' | uni2ascii -aE -qps; } -# декодирование символов из HEX кодов и удаление разделителей строк -function decode { echo "$1" | ascii2uni -aE -q | tr -d '\r\n'; } +# кодирование символов в HEX коды [U0000-UFFFF] +function encode { echo "$1" | uni2ascii -aE -qps; } +# декодирование символов из HEX кодов [U0000-UFFFF] +function decode { echo "$1" | ascii2uni -aE -q; } # перечисление используемых функций в дочерних процессах bash export -f decode first_func second_func third_func #---------------------------------------------------------------------------; @@ -60,33 +59,33 @@ p1="$(encode "$param1")" p2="$(encode "$param2")" # массив строк — вызовы функций с параметрами array[0]="first_func '$p0' '$p1' '$p2'" -array[1]="second_func '$p2' '$p0' '$p1'" -array[2]="third_func '$p1' '$p2' '$p0'" +array[1]="second_func '$p1' '$p2' '$p0'" +array[2]="third_func '$p2' '$p0' '$p1'" # вывод строк массива для наглядности printf '%s\n' "${array[@]}" #---------------------------------------------------------------------------; -# параллельный вызов функций и замер общего времени выполнения +# параллельное выполнение функций и замер общего времени выполнения #---------------------------------------------------------------------------; # текущее время в миллисекундах time_ms="$(date '+%s%3N')" # вывод строк массива и вызов функции для каждой из них в параллельном режиме -printf '%s\0' "${array[@]}" | xargs -I{} -n1 -0 -P0 bash -c 'eval "{}"' +printf '%s\0' "${array[@]}" | xargs -I{} -n1 -0 -P0 bash -c "{}" # время работы в миллисекундах echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс." ``` ## Вывод -Строки массива, вызовы функций с параметрами через пробелы в кавычках +Строки массива — вызовы функций с параметрами через пробелы в кавычках ``` first_func 'U0020U0024U0070U0061U0072U0061U006DU0022' '' 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' -second_func 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' '' -third_func '' 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' +second_func '' 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' +third_func 'U0022U0024U0032U0022U0021U003DU0022U0024U0031U0022' 'U0020U0024U0070U0061U0072U0061U006DU0022' '' ``` Параллельная работа функций, порядок может изменяться ``` -3 third_func [] ["$2"!="$1"] [ $param"] -2 second_func ["$2"!="$1"] [ $param"] [] +3 third_func ["$2"!="$1"] [ $param"] [] +2 second_func [] ["$2"!="$1"] [ $param"] 1 first_func [ $param"] [] ["$2"!="$1"] ``` Время работы функций в миллисекундах diff --git a/bash_scripts/info_param.sh b/bash_scripts/info_param.sh index d3ddfe5..2e0aa98 100755 --- a/bash_scripts/info_param.sh +++ b/bash_scripts/info_param.sh @@ -1,5 +1,5 @@ #!/bin/bash -#remote="gitea.com" -remote="git.org.ru" -#remote="hub.mos.ru" -echo "Переключение домена удалённого репозитория: $remote" +#domain="gitea.com" +domain="git.org.ru" +#domain="hub.mos.ru" +echo "Переключение домена удалённого репозитория: $domain" diff --git a/bash_scripts/info_references.sh b/bash_scripts/info_references.sh index 2e544f5..3f608ff 100755 --- a/bash_scripts/info_references.sh +++ b/bash_scripts/info_references.sh @@ -1,13 +1,11 @@ #!/bin/bash echo "Обновление домена удалённого репозитория в перекрёстных ссылках в описаниях." -export remote="git.org.ru" && source info_param.sh -# экранируем точки в названии домена -export domain="${remote//"."/"\."}" +export domain="git.org.ru" && source info_param.sh # название домена в верхнем регистре export DOMAIN="${domain^^}" # обработка информационных файлов function references { - echo "$remote => $1" + echo "$domain => $1" # сбрасываем значения параметров sed -i "s|gitea\.com|tmp_stub|g" "$1" sed -i "s|GITEA\.COM|TMP_STUB|g" "$1" @@ -18,7 +16,7 @@ function references { # устанавливаем значения параметров sed -i "s|tmp_stub|$domain|g" "$1" sed -i "s|TMP_STUB|$DOMAIN|g" "$1" - if [ "$remote" == "hub.mos.ru" ]; then + if [ "$domain" == "hub.mos.ru" ]; then sed -i "s|src/branch|blob|g" "$1" else sed -i "s|blob|src/branch|g" "$1" diff --git a/bash_scripts/info_tree_license.sh b/bash_scripts/info_tree_license.sh index fd7a672..719b4f5 100755 --- a/bash_scripts/info_tree_license.sh +++ b/bash_scripts/info_tree_license.sh @@ -23,14 +23,14 @@ function directory_tree { if [ -d "$path" ]; then local list # массив файлов и каталогов readarray -t list <<<"$(list_directory_contents "$path")" - local len=${#list[@]} # размер массива + local size=${#list[@]} # длина массива local i # счётчик - for ((i = 0; i < len; i++)); do + for ((i = 0; i < size; i++)); do if [ -z "${list[$i]}" ]; then continue # пропустить пустой каталог - elif ((len == 1)); then + elif ((size == 1)); then directory_tree "$path/${list[$i]}" "$tail" "$tail" "one" - elif ((i < len - 1)); then + elif ((i < size - 1)); then directory_tree "$path/${list[$i]}" "$tail├─ " "$tail│ " else directory_tree "$path/${list[$i]}" "$tail└─ " "$tail " diff --git a/bash_scripts/repo_compose.sh b/bash_scripts/repo_compose.sh index 79aa168..9377704 100755 --- a/bash_scripts/repo_compose.sh +++ b/bash_scripts/repo_compose.sh @@ -1,6 +1,6 @@ #!/bin/bash echo "Создание скриптов из шаблонов с параметрами и сохранение их в каталогах проектов." -export remote="git.org.ru" && source info_param.sh +export domain="git.org.ru" && source info_param.sh export basedir="$PWD" # текущая папка # обновление списка исключений function update_gitignore { @@ -43,7 +43,7 @@ function compose { fi wiki="" # оглавление по страницам вёб-сайта if [ -f "$dir/WIKI.md" ]; then - if [ "$remote" == "hub.mos.ru" ]; then + if [ "$domain" == "hub.mos.ru" ]; then wiki="$(uni2ascii -aU -qpsn "$dir/WIKI.md")" else wiki="$(basenc "$dir/WIKI.md" --base64 -w0)" @@ -52,13 +52,13 @@ function compose { # скрипт для создания удалённого репозитория { echo "#!/bin/bash" - echo "remote=\"$remote\"" + echo "domain=\"$domain\"" echo "owner=\"$owner\"" echo "user=\"golovin\"" echo "repo=\"$repo\"" echo "description=\"$description\"" echo "wiki=\"$wiki\"" - if [ "$remote" == "hub.mos.ru" ]; then + if [ "$domain" == "hub.mos.ru" ]; then echo "token=\"$(cat "$basedir/.token_gitlab")\"" cat "$basedir/repo_gitlab.tmpl.sh" else @@ -69,7 +69,7 @@ function compose { # скрипт для создания локального репозитория { echo "#!/bin/bash" - echo "remote=\"$remote\"" + echo "domain=\"$domain\"" echo "owner=\"$owner\"" echo "repo=\"$repo\"" echo "dir=\"$dir\"" diff --git a/bash_scripts/repo_gitea.tmpl.sh b/bash_scripts/repo_gitea.tmpl.sh index ba56d3d..58e6755 100644 --- a/bash_scripts/repo_gitea.tmpl.sh +++ b/bash_scripts/repo_gitea.tmpl.sh @@ -1,4 +1,4 @@ -if [ -z "$remote" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then +if [ -z "$domain" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then echo "Не указаны обязательные параметры." && exit 1 fi if [ -z "$1" ]; then @@ -8,7 +8,7 @@ seconds=5 time_ms="$(date '+%s%3N')" if [ -z "$1" ] || [ "$1" == "delete" ]; then echo "Удаление старого репозитория." - curl -X DELETE "https://$remote/api/v1/repos/$owner/$repo" \ + curl -X DELETE "https://$domain/api/v1/repos/$owner/$repo" \ -H "Authorization: token $token" \ -H "Accept: application/json" -i echo "Ожидание $seconds с." @@ -16,7 +16,7 @@ if [ -z "$1" ] || [ "$1" == "delete" ]; then fi if [ -z "$1" ] || [ "$1" == "create" ]; then echo "Создание нового репозитория пользователя." - curl -X POST "https://$remote/api/v1/user/repos" \ + curl -X POST "https://$domain/api/v1/user/repos" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"name\": \"$repo\", \"description\": \"$description\" }" -i @@ -24,7 +24,7 @@ if [ -z "$1" ] || [ "$1" == "create" ]; then sleep "$seconds" if [ "$user" != "$owner" ]; then echo "Перемещение репозитория в группу." - curl -X POST "https://$remote/api/v1/repos/$user/$repo/transfer" \ + curl -X POST "https://$domain/api/v1/repos/$user/$repo/transfer" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"new_owner\": \"$owner\" }" -i @@ -35,7 +35,7 @@ fi if [ -z "$1" ] || [ "$1" == "options" ]; then if [ "$wiki" ]; then echo "Добавление страницы wiki в репозиторий." - curl -X POST "https://$remote/api/v1/repos/$owner/$repo/wiki/new" \ + curl -X POST "https://$domain/api/v1/repos/$owner/$repo/wiki/new" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"content_base64\": \"$wiki\", \"title\": \"Home\" }" -i @@ -44,7 +44,7 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then has_wiki=false fi echo "Изменение свойств репозитория / отключение ненужного." - curl -X PATCH "https://$remote/api/v1/repos/$owner/$repo" \ + curl -X PATCH "https://$domain/api/v1/repos/$owner/$repo" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ @@ -61,7 +61,7 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then picture="website" fi avatar=$(basenc "../pomodoro/pictures/$picture.jpg" --base64 -w0) - curl -X POST "https://$remote/api/v1/repos/$owner/$repo/avatar" \ + curl -X POST "https://$domain/api/v1/repos/$owner/$repo/avatar" \ -H "Authorization: token $token" \ -H "Accept: application/json" \ -H "Content-Type: application/json" -d "{ \"image\": \"$avatar\" }" -i diff --git a/bash_scripts/repo_gitlab.tmpl.sh b/bash_scripts/repo_gitlab.tmpl.sh index 0fceb98..dc4b0be 100644 --- a/bash_scripts/repo_gitlab.tmpl.sh +++ b/bash_scripts/repo_gitlab.tmpl.sh @@ -1,4 +1,4 @@ -if [ -z "$remote" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then +if [ -z "$domain" ] || [ -z "$token" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$description" ] || [ -z "$user" ]; then echo "Не указаны обязательные параметры." && exit 1 fi if [ -z "$1" ]; then @@ -8,7 +8,7 @@ seconds=5 time_ms="$(date '+%s%3N')" if [ -z "$1" ] || [ "$1" == "delete" ]; then echo "Удаление старого репозитория." - curl -i -X DELETE "https://$remote/api/v4/projects/$owner%2F$repo" \ + curl -i -X DELETE "https://$domain/api/v4/projects/$owner%2F$repo" \ -H "PRIVATE-TOKEN: $token" \ -H "Content-Type: application/json" -d "{\"permanently_remove\": \"true\", \"full_path\": \"$owner/$repo\"}" echo @@ -17,7 +17,7 @@ if [ -z "$1" ] || [ "$1" == "delete" ]; then fi if [ -z "$1" ] || [ "$1" == "create" ]; then echo "Создание нового репозитория пользователя." - curl -i -X POST "https://$remote/api/v4/projects" \ + curl -i -X POST "https://$domain/api/v4/projects" \ -H "PRIVATE-TOKEN: $token" \ -H "Content-Type: application/json" -d "{\"name\": \"$repo\", \"description\": \"$description\"}" echo @@ -25,7 +25,7 @@ if [ -z "$1" ] || [ "$1" == "create" ]; then sleep "$seconds" if [ "$user" != "$owner" ]; then echo "Перемещение репозитория в группу." - curl -i -X PUT "https://$remote/api/v4/projects/$user%2F$repo/transfer?namespace=$owner" \ + curl -i -X PUT "https://$domain/api/v4/projects/$user%2F$repo/transfer?namespace=$owner" \ -H "PRIVATE-TOKEN: $token" echo echo "Ожидание $seconds с." @@ -35,7 +35,7 @@ fi if [ -z "$1" ] || [ "$1" == "options" ]; then if [ "$wiki" ]; then echo "Добавление страницы wiki в репозиторий." - curl -i -X POST "https://$remote/api/v4/projects/$owner%2F$repo/wikis" \ + curl -i -X POST "https://$domain/api/v4/projects/$owner%2F$repo/wikis" \ -H "PRIVATE-TOKEN: $token" \ -H "Content-Type: application/json" -d "{\"content\": \"$wiki\", \"title\": \"Home\"}" echo @@ -44,7 +44,7 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then has_wiki="disabled" fi echo "Изменение свойств репозитория / отключение ненужного." - curl -i -X PUT "https://$remote/api/v4/projects/$owner%2F$repo" \ + curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \ -H "PRIVATE-TOKEN: $token" \ -H "Content-Type: application/json" -d "{ \"emails_disabled\": \"true\", @@ -87,7 +87,7 @@ if [ -z "$1" ] || [ "$1" == "options" ]; then if [ "$user" != "$owner" ]; then picture="website" fi - curl -i -X PUT "https://$remote/api/v4/projects/$owner%2F$repo" \ + curl -i -X PUT "https://$domain/api/v4/projects/$owner%2F$repo" \ -H "PRIVATE-TOKEN: $token" \ -F "avatar=@../pomodoro/pictures/$picture.jpg" echo diff --git a/bash_scripts/repo_local.tmpl.sh b/bash_scripts/repo_local.tmpl.sh index 2a1054c..8d3a78c 100644 --- a/bash_scripts/repo_local.tmpl.sh +++ b/bash_scripts/repo_local.tmpl.sh @@ -1,4 +1,4 @@ -if [ -z "$remote" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$dir" ]; then +if [ -z "$domain" ] || [ -z "$owner" ] || [ -z "$repo" ] || [ -z "$dir" ]; then echo "Не указаны обязательные параметры." && exit 1 fi echo "Создание локального репозитория, подключение к удалённому и передача данных." @@ -6,12 +6,12 @@ seconds=3 time_ms="$(date '+%s%3N')" rm -rf .git git init -b master -git remote add "$remote" "git@$remote:$owner/$repo.git" +git remote add "$domain" "git@$domain:$owner/$repo.git" git add .git* git commit -m "Инициализация / $dir" -if [ "$remote" == "hub.mos.ru" ]; then +if [ "$domain" == "hub.mos.ru" ]; then echo "Второй пуш, потому что лингвист с первого раза не срабатывает." - git push -u "$remote" master + git push -u "$domain" master echo "Ожидание $seconds с." sleep $seconds fi @@ -46,5 +46,5 @@ find . -type f -not -path "*/.*" -not -path "./_site*" | LC_COLLATE=C sort -r | git add "$file" git commit -m "${file#*/}" done -git push -u "$remote" master +git push -u "$domain" master echo "Общее время выполнения: $(("$(date '+%s%3N')" - "$time_ms")) мс."