Универсальное `при чтении чего-либо `в `параллельное `преобразование/замена

Похоже, вы достаточно хорошо подготовились, --не хватает только одного важного :режима BIOS, в котором вы хотите запустить свою систему.

Ваша модель кажется немного устаревшей, и я не нашел упоминания uefi. Это не проблема. Это означало бы, что вы просто остаетесь в «устаревшем» (или MBR, вашем единственном )режиме загрузки BIOS.

Я перечислил несколько сценариев загрузки в похожей ситуации :grub2 -не удалось -до -обнаружить -a -свежую -... -установку

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

Если вам повезет, программа установки Ubuntu поможет вам, и все должно работать. Получите некоторую конкретную информацию из вики ubuntu и т. д. после того, как прочитаете это. Но прежде чем установить ;)

В ваших двух -дисковых -двойных -загрузочных я вижу два метода выбора при запуске:

  1. перейдите в BIOS для каждого изменения порядка загрузки (так же, как вы можете выбрать CD -ROM для загрузки ).
  2. загрузитесь как сейчас в первый grub . Затем grub может найти второе ядро ​​и initrd и загрузить их со вторым аргументом root=. ИЛИ цепная нагрузка вторая жратва -как у вас на MBR и (старая? )лило.

Grub или Uefi BIOS являются связующим звеном между устаревшей прошивкой компьютера и ядром при запуске (загрузка системы ):Должна быть в нужном месте, гайка просто «там».

Ознакомьтесь с grub или uefi в Википедии, чтобы по-иному взглянуть на эти интересные, но каверзные проблемы при загрузке ОС.

Любая ОС . БИОС и тоже grub как раз и сделаны для запуска любой ОС, и для выбора какой именно при запуске. Linux, BSD и т. д., Windows :любая ОС, работающая на процессорах amd64/intel, также известных как x86.

И всегда убедитесь, что вы знаете, как использовать вашу систему восстановления с внешнего накопителя (USB-ручку )на случай, если вы что-то сломаете -добавление второго внутреннего диска (SSD или HDD )для загрузки с MBR — это довольно большой шаг.

2
16.06.2021, 05:16
3 ответа

Можно заставить bash или ksh выполнять список независимых команд одновременно, так что каждый поток начинает новую команду, как только завершается его предыдущая задача. Потоки остаются занятыми, за исключением хвостовых команд завершения -.

Основной метод заключается в запуске нескольких асинхронных оболочек, которые все считывают из одного и того же канала :канал гарантирует строку -буферизацию и атомарное чтение (файл команд можно использовать с cat file | , но не перенаправлением ).

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

Это тестовый запуск шести заданий в трех потоках, иллюстрирующий перекрытие заданий. (Я подчеркиваю, что -протестировал 240 заданий в 80 потоках на моем ноутбуке.)

Time now 23:53:47.328735254
Sleep until 00 seconds to make debug easier.
Starting 3 Streams
23:54:00.040   Shell   1 Job   1 Go    sleep 5
23:54:00.237   Shell   2 Job   2 Go    sleep 13
23:54:00.440   Shell   3 Job   3 Go    sleep 14
Started all Streams
23:54:05.048   Shell   1 Job   1   End sleep 5
23:54:05.059   Shell   1 Job   4 Go    sleep 3
23:54:08.069   Shell   1 Job   4   End sleep 3
23:54:08.080   Shell   1 Job   5 Go    sleep 13
23:54:13.245   Shell   2 Job   2   End sleep 13
23:54:13.255   Shell   2 Job   6 Go    sleep 3
23:54:14.449   Shell   3 Job   3   End sleep 14
23:54:16.264   Shell   2 Job   6   End sleep 3
23:54:21.089   Shell   1 Job   5   End sleep 13
All Streams Ended

Это прокси-скрипт, обеспечивающий отладку этих заданий.

#! /bin/bash

#.. jobProxy.
#.. arg 1: Job number.
#.. arg 2: Sleep time.
#.. idStream: Exported into the Stream's shell.

    fmt='%.12s   Shell %3d Job %3d %s sleep %s\n'
    printf "${fmt}" $( date '+%T.%N' ) "${idStream}" "${1}" "Go   " "${2}"
    sleep "${2}"
    printf "${fmt}" $( date '+%T.%N' ) "${idStream}" "${1}" "  End" "${2}"

Это сценарий управления потоком. Он создает команды заданий для запуска прокси-серверов и запускает фоновые оболочки.

#! /bin/bash

makeJobs () {

    typeset nJobs="${1}"

    typeset Awk='
BEGIN { srand( Seed % 10000000); fmt = "./jobProxy %s %3d\n"; }
{ printf (fmt, $1, 2 + int (14 * rand())); }
'
    seq 1 "${nJobs}" | awk -v Seed=$( date "+%N$$" ) "${Awk}"
}

runStreams () {

    typeset n nStreams="${1}"

    echo "Starting ${nStreams} Streams"
    for (( n = 1; n <= nStreams; ++n )); do
        idStream="${n}" bash -s &
        sleep 0.20
    done
    echo "Started all Streams"

    wait
    echo "All Streams Ended"
}

## Script Body Starts Here.

    date '+Time now %T.%N'
    echo 'Sleep until 00 seconds to make debug easier.'
    sleep $( date '+%S.%N' | awk '{ print 60 - $1; }' )

    makeJobs 6 | runStreams 3
0
28.07.2021, 11:24

Вместо многократного запуска git ls-tree, а затем git log, dateи touchв цикле bash while read, следующий скрипт perl берет вывод git log --name-only HEADи сохраняет самую последнюю метку времени для любой файл, упомянутый в журнале коммитов в хеше с именем %files. Он игнорирует имена файлов, которые не существуют.

Затем он строит хэш массивов ("HoA" -см.man perldsc)с именем %times, с временными метками в качестве хеш-ключа и значениями, представляющими собой анонимный массив, содержащий имена файлов с этой временной меткой. Это оптимизация, так что сенсорную функцию нужно запускать только один раз для каждой метки времени, а не один раз для каждого имени файла.

Идентификатор фиксации, сообщение фиксации, имя автора и пустые строки из вывода git logигнорируются.

Сценарий использует функцию unqqbackslash()из String ::Escape для каждого имени файла, чтобы правильно обрабатывать способ, которым git logпечатает имена файлов со встроенными табуляторами, новыми строками, двойными -кавычками и т. д. (т. е. как строки в двойных -кавычках с экранированными кодами/символами обратной косой черты ).

Я ожидаю, что он должен работать как минимум в десятки раз быстрее, чем ваш цикл bash.

#!/usr/bin/perl

use strict;
use Date::Parse;
use File::Touch;
use String::Escape qw(unqqbackslash);

my %files = ();
my %times = ();
my $t;

while (<>) {
  chomp;
  next if (m/^$|^\s+|^Author: |^commit /);

  if (s/^Date:\s+//) {
    $t = str2time($_);

  } else {
    my $f = unqqbackslash($_);
    next unless -e $f;   # don't create file if it doesn't exist

    if (!defined($files{$f}) || $files{$f} < $t) {
      $files{$f} = $t;
    }

  };
};

# build %files HoA with timestamps containing the
# files modified at that time.
foreach my $f (sort keys %files) {
  push @{ $times{$files{$f}} }, $f;
}

# now touch the files
foreach my $t (keys %times) {
  my $tch = File::Touch->new(mtime_only => 1, time => $t);
  $tch->touch(@{ $times{$t} });
};

Скрипт использует Perl-модули Date ::Parse , File ::Touch и String ::Escape .

В Debian, apt install libtimedate-perl libfile-touch-perl libstring-escape-perl. В других дистрибутивах они, вероятно, тоже упакованы. В противном случае установите их с помощью cpan.

Пример использования в репозитории git с парой ненужных файлов(fileиfile2):

$ git log --date=format:'%Y-%m-%d %H:%M:%S' --pretty='%H  %ad %s' file*
d10c313abb71876cfa8ad420b10f166543ba1402  2021-06-16 14:49:24 updated file2
61799d2c956db37bf56b228da28038841c5cd07d  2021-06-16 13:38:58 added file1
                                                              & file2

$ touch file*
$ ls -l file*
-rw-r--r-- 1 cas cas  5 Jun 16 19:23 file1
-rw-r--r-- 1 cas cas 29 Jun 16 19:23 file2

$ git  log  --name-only HEAD file*  |./process-git-log.pl 
$ ls -l file*
-rw-r--r-- 1 cas cas  5 Jun 16 13:38 file1
-rw-r--r-- 1 cas cas 29 Jun 16 14:49 file2

(немного сфальсифицировано -Я отредактировал сообщения фиксации, чтобы было ясно, когда оба файла были впервые зафиксированы, затем файл2 был изменен и зафиксирован снова. Кроме этого, это копия -, вставленная непосредственно с моего терминала ).


Это моя вторая попытка :Первоначально я пытался использовать модуль Git ::Raw , но не мог понять, как получить список только ] имена файлов, измененных в конкретной фиксации. Я уверен, что есть способ, но я отказался от этого. Я просто недостаточно хорошо знаю внутренности git.

0
28.07.2021, 11:24

Я бы использовал функцию bash и назвал бы ее:

myfunc() {
   filename="$1"
   unixtime=$(git log -1 --format="%at" -- "${filename}");
   touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S');
   touch -t ${touchtime} "${filename}";
}
export -f myfunc

git ls-tree -r --name-only HEAD | parallel myfunc

Используйте parallel -0, если вы хотите разделить на NUL.

Если вы хотите запустить вышеуказанное без установки GNU Parallel, вы можете использовать:

parallel --embed > myscript.sh

, а затем добавьте указанное выше к myscript.sh.

1
28.07.2021, 11:24

Теги

Похожие вопросы