Как оказалось (по советам данным на linux.org.ru), наиболее правильным вариантом обновления существующей инсталляции httpd, является «опакечивание» исходных кодов в rpm, а затем штатная его установка. В этом случаем мы избавляемся от проблем с выбором правильных ключей и путей, которые пришлось бы устанавливать руками при компиляции/сборке httpd из исходников. Итак поехали:
Если сборка вываливается с ошибками, то необходимо смотреть файл config.log и до устанавливать необходимые зависимости (смотря на что ругается)
Если сборка прошла успешно, то в папке ~/rpmbuild/RPMS/x86_64 будут пакеты готовые к установке. Устанавливать их можно штатно:
rmp -U *.rpm --force
ключ —force в данном случае нужен для того, чтобы установщик не ругался на уже существующие файлы настройки httpd (вот тут осторожно! лучше сначала попробовать без этого ключа и посмотреть ошибки)
Ситуация: после обновления с RedOS 7.3 до RedOS 8.0, обновился и интерпретатор PHP с 7.4. до 8.1, что к сожалению сломало работу сайта на Bitrix. Нужна установка PHP 7.4 на RedOS 8.0
Задача: сделать даунгрейд PHP 8.1 на PHP 7.4
Решение: Штатным образом в RedOS 8.0 отсутствует возможность установки PHP 7.4, Но! так как RedOS по сути своей совместим с RedHat/CentOS, значит возможно использовать сторонние репозитарии http://rpms.remirepo.net.
Создадим в папке /etc/yum.repos.d файл remi.repo с содержимым:
# This repository only provides PHP 7.4 and its extensions
# NOTICE: common dependencies are in "remi-safe"
[remi-php74]
name=Remi's PHP 7.4 RPM repository for Enterprise Linux 7 - $basearch
baseurl=http://rpms.remirepo.net/enterprise/7/php74/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi
Долго ли, коротко ли, но вот взяло и перестало работать реле времени на моём септике на даче. Его задачей было — раз в час, включать на 15 минут циркуляционный дренажный насос. А так как покупать новое реле «это не наш метод», было принято решение разработать реле времени своими руками. Максимально дешевое, максимально компактное. Итак, именно поэтому будем использовать микросхему attiny85:
Купить её можно дешевле 100 руб. Так-же из хотелок, подумал , что не плохо бы видеть сколько осталось времени до включения реле и выключения реле. Следовательно будем использовать семи сегментый индикатор.
Включением-выключением насоса будет заниматься реле:
Чуть посчитав количество требуемых ног у микросхемы, взгруснул — для индикатора требуется 7 ног, плюс на реле одна. А у микросхемы всего 6 выходов. Значит придётся использовать сдвиговый регистр. Задача уже не получается совсем простой, но тем не менее остаётся вполне решаемой.
Сдвиговый регистр я уже использовал ранее в своих разработках, подробнее о нём можно почитать здесь.
Итак, вырисовался в конце концов следующий алгоритм работы всего этого набора электронники: на индикаторе последовательно сменяются цифры от 9 до 0. Цифры сменяются с интервалом в 6 минут. При достижении 1, включается реле, которое выключается при достижении 0. И так по циклу. Т.е. реле (ну и насос) работает 12 минут из часа.
Общая схема подключения получилась такой:
А скетч такой:
int dataPin = 1; // к выводу 14 регистра DS
int clockPin = 2; // к выводу 11 регистра (SH_CP)
int latchPin = 0; // к выводу 12 регистра (ST_CP)
int PIN_RELAY= 4; // управление реле
int pause=1000; // интервал переключения цифр
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
digitalWrite(latchPin, LOW);
digitalWrite(PIN_RELAY, HIGH); // Выключаем реле - посылаем высокий сигнал
}
void PritNum(int num){
digitalWrite(latchPin, LOW); // начинаем передачу данных
switch(num){
case 0:
shiftOut(dataPin, clockPin, LSBFIRST, 0b10001000^0b00001000);break;
case 1:
shiftOut(dataPin, clockPin, LSBFIRST, 0b11101011);break;
case 2:
shiftOut(dataPin, clockPin, LSBFIRST, 0b01001100);break;
case 3:
shiftOut(dataPin, clockPin, LSBFIRST, 0b01001001);break;
case 4:
shiftOut(dataPin, clockPin, LSBFIRST, 0b00101011);break;
case 5:
shiftOut(dataPin, clockPin, LSBFIRST, 0b00011001);break;
case 6:
shiftOut(dataPin, clockPin, LSBFIRST, 0b00011000);break;
case 7:
shiftOut(dataPin, clockPin, LSBFIRST, 0b11001011);break;
case 8:
shiftOut(dataPin, clockPin, LSBFIRST, 0b00001000);break;
case 9:
shiftOut(dataPin, clockPin, LSBFIRST, 0b00001001);break;
}
digitalWrite(latchPin, HIGH); // прекращаем передачу данных
}
void loop() {
for (int counter = 9; counter >=0; counter -- ) {
PritNum(counter);
pinMode(PIN_RELAY, OUTPUT); // Объявляем пин реле как выход
if (counter==0){
digitalWrite(PIN_RELAY, HIGH);
};
if (counter!=0){
digitalWrite(PIN_RELAY, LOW);
};
delay(pause);
}
}
Задача: есть два массива структур. Один 500 записей, второй — порядка 900 тыс. Нужно для каждой из 500 записей, найти соответствующую запись из второй структуры.
Массив «субабоненты», заполнен структурами вида «то,лс,ипу,окпу,нс,улица,дом,квартира»
Массив «реестр_замен», заполнен структурами вида «лс,нп,улица,дом,квартира,ипу,дата_установки»
Решение 1: ищем и сопоставляем в «лоб»
найдено=0;
для каждого суб из ИсходныеДанные.субабоненты цикл
поз=поз+1;
для каждого стр из ИсходныеДанные.реестр_замен цикл
если суб.лс=стр.лс тогда
найдено=найдено+1;
конецесли;
конеццикла;
конеццикла;
сообщить("-сопоставлено лс: "+найдено);
Замеряем время выполнения…и устаём ждать.. Поиск и сопоставление длится по крайне мере несколько часов..
Решение 2:
А зачем нам в массиве субабонентов держать те данные, которых нет? Правильно, не зачем. Поэтому из массива «реестр_замен», сначала вычленим список л/с, и положим его в отдельный массив. И далее при заполнении из файла массива субабонентов, нужно штатно (функция Найти) проверять нужна такая строчка или нет в результирующем массиве? Функция «Найти» скажем работает ОЧЕНЬ быстро.
если ИсходныеДанные.список_лс.Найти(инф.лс)<>неопределено или ИсходныеДанные.список_ипу.Найти(инф.ипу)<>неопределено тогда
ИсходныеДанные.субабоненты.Добавить(инф);
конецесли;
В итоге, в массиве «субабоненты» у нас ровно то количество записей, которое в «реестр_замен «, а вовсе не 900тыс.
И дальше пробуем снова сопоставить:
найдено=0;
для каждого суб из ИсходныеДанные.субабоненты цикл
поз=поз+1;
для каждого стр из ИсходныеДанные.реестр_замен цикл
если суб.лс=стр.лс тогда
найдено=найдено+1;
конецесли;
конеццикла;
конеццикла;
сообщить("-сопоставлено лс: "+найдено);
Скрипт выполнился уже в приемлемые примерно 400 секунд
Куда ни глянь, в интернете чаще всего предлагается обработка и чтение большого файла csv в 1С при помощи загрузки в «текстовыйДокумент». Примерно так:
ТекстДок = Новый ТекстовыйДокумент; ТекстДок.Прочитать(ИмяВременногоФайлаХар); Для Индекс = 2 По ТекстДок.КоличествоСтрок() Цикл СтрокаФайла = ТекстДок.ПолучитьСтроку(Индекс); конеццикла;
Что в корне не верно, при обработке большого csv файла, так как в этом случае весь файл вычитывается предварительно в память. А она не безразмерная в большинстве случаев. Правильный же способ обработки — построчное чтение файла. Примерно так:
Текст = Новый ЧтениеТекста(ИмяВременногоФайлаХар, КодировкаТекста.ANSI);
Стр = Текст.ПрочитатьСтроку();
Пока Стр <> Неопределено Цикл
Сообщить(Стр);
Стр = Текст.ПрочитатьСтроку();
МассивПодстрок = СтрРазделить(Стр, ";");
инф=Новый Структура("то,лс,ипу,окпу,нс,улица,дом,квартира");
инф.то =СокрЛП(МассивПодстрок[2]);
инф.лс =СокрЛП(СтрЗаменить(МассивПодстрок[3],"-",""));
инф.ипу =СокрЛП(МассивПодстрок[31]);
инф.окпу =СокрЛП(МассивПодстрок[92]);
инф.нс =СокрЛП(МассивПодстрок[8]);
инф.улица =СокрЛП(МассивПодстрок[9]);
инф.дом =СокрЛП(МассивПодстрок[10]);
инф.квартира=СокрЛП(МассивПодстрок[11]);
ИсходныеДанные.субабоненты.Добавить(инф);
КонецЦикла;