вторник, 30 января 2018 г.

Памятка: замена одного RPM пакета, другим в одной операции

Суть:
    Требуется использовать (в Red Hat based линуксах) команду yum shell
  • yum shell
  • remove <old_package>
  • install <new_package>
  • run
  • ....
  • exit

 Предистория
     Требовалось установить свою реализацию NTP-сервера/клиента вместо стандартного для Oracle Linux пакета ntp. В своём пакете (tssd) прописано, что он предоставляет функционал ntp (Provides: ntp внутри spec-файла). Помимо этого указано, что он конфликтует с ntp (что бы они сразу хором время не подводили). Итого: если попытаться установить сначала tssd - то получим конфликт, что сначала надо удалить ntp. Если сначала удалить ntp - то  зависимые от него системные пакеты тоже удалятся, а они могут быть важны и удалять их не стоит.

Пример выполнения
   Ниже приведён лог замены ntp на tssd.

[root@grinVMOL6x86 ~]# yum shell
Loaded plugins: security
Setting up Yum Shell
> remove ntp
Setting up Remove Process
> install tssd
Setting up Install Process
> run
--> Running transaction check
---> Package ntp.i686 0:4.2.6p5-12.0.1.el6_9.2 will be erased
---> Package tssd.i686 0:1.4-75 will be installed
--> Finished Dependency Resolution

================================================================
 Package Arch  Version                 Repository          Size
================================================================
Installing:
 tssd    i686  1.4-75                  topaz               118 k
Removing:
 ntp     i686  4.2.6p5-12.0.1.el6_9.2  @public_ol6_latest  1.6 M

Transaction Summary
================================================================
Install       1 Package(s)
Remove        1 Package(s)

Total download size: 118 k
Is this ok [y/N]: y
Downloading Packages:
tssd-1.4-75.i686.rpm                                                                                                                                                                                            | 118 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : tssd-1.4-75.i686                              1/2 
tssd start/running, process 7303
  Erasing    : ntp-4.2.6p5-12.0.1.el6_9.2.i686               2/2 
  Verifying  : tssd-1.4-75.i686                              1/2 
  Verifying  : ntp-4.2.6p5-12.0.1.el6_9.2.i686               2/2 

Removed:
  ntp.i686 0:4.2.6p5-12.0.1.el6_9.2                                                                                                                                                                                                    

Installed:
  tssd.i686 0:1.4-75                                                                                                                                                                                                                   

Finished Transaction
> exit
Leaving Shell
[root@grinVMOL6x86 ~]#

среда, 17 января 2018 г.

Памятка: конвертация исходников CP-1251 в UTF-8 (Linux)

В долгоживущем проекте, который уже перенесли на линукс малая часть исходников была в кодировке CP-1251 (Windows 1251). А основная часть в кодировке UTF-8. Требовалось без затей перекодировать в UTF-8 указанную малую часть.

Выполнили следующим скриптом:

for incorrect_file in $(for file in $(find $(pwd) -type f | grep -E "*\.h$|*\.c$|*\.hpp$|*\.cpp$"); do file -i ${file}; done | grep charset=iso-8859-1 | awk 'BEGIN{FS=":"}{print $1}'); do echo ${incorrect_file}; iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file}; done

Более читаемая форма:

files=$(find $(pwd) -type f | grep -E "*\.h$|*\.c$|*\.hpp$|*\.cpp$"); \
incorrect_files=$( for_ file in ${files}; do \
                                  file -i ${_file}; \
                              done | \
                              grep charset=iso-8859-1 | \
                              awk 'BEGIN{FS=":"}{print $1}'); \
for incorrect_file in ${incorrect_files} do \
    echo ${incorrect_file}; \
    iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file}; \
done

Разбор:
  • find $(pwd) -type f - ищет рекурсивно все файлы вглубь относительно текущей директории
  • grep -E "\.h$|\.c$|\.hpp$|.\cpp$" - фильтр - выводит в stdout только файлы с раширениями: .h .c .hpp .cpp
  • file -i ${file} - выдаёт информацию о файле, включая его кодировку
  • grep charset=iso-8859-1 - фильтр - выводит в stdout только информацию по файлам, имеющим указанную кодировку. Суть в том, что для файла с фактической кодировкой CP1251 команда file  -i выводит информацию, что кодировка iso-8859-1.
  • awk 'BEGIN {FS=":"}{print $1}' из отфильтрованной строки команды file -i выводит только имя файла.
  • iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file} - собственно перекодирует файл из кодировки CP1251 в UTF-8.