Записки IT специалиста
8.97K subscribers
2.41K photos
39 videos
16 files
2.44K links
IT-канал, просто о сложном
https://interface31.ru

Купить рекламу:
https://telega.in/c/interface31
Download Telegram
Тонкие настройки LXC. Процессор

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

Для примера возьмем задачу, когда у нас есть некоторый процессор 16 ядер / 32 потока и мы хотим разместить на нем сервер 1С, сервер СУБД и всяко-разно по мелочи.

Сервер 1С версии ПРОФ может использовать не более 12 ядер, но просто взять и указать в его настройках ограничение по ядрам мы не можем, потому что при старте контейнер будет выбирать ядра случайным образом, что ведет к изменению процессора и слету лицензии 1С.

Поэтому укажем ядра явно, для этого в конфигурационный файл /etc/pve/lxc/nnn.conf (где nnn – ID контейнера) добавим:

lxc.cgroup2.cpuset.cpus = 0-11


Это заставит его использовать 12 первых ядер. Ядра нумеруются начиная с нуля. Можно указывать отдельные номера через запятую или диапазон через тире, оба способа можно комбинировать. Например:

lxc.cgroup2.cpuset.cpus = 0, 1, 8-10,17-20


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

Поэтому явно указываем доступные ядра и для других машин, скажем 12-23 серверу СУБД и диапазон 24-31 для всех остальных.

В многопроцессорных системах дополнительно можно указать номер узла NUMA который может использовать контейнер, это позволит избежать задержек, когда процессор работая на ядрах одного процессора будет обращаться к памяти, которую обслуживает другой процессор.

Для этого используйте:

lxc.cgroup2.cpuset.mems: 0


Где цифра указывает номер узла NUMA начиная с нуля, можем указать несколько значений с нуля или через запятую.

Хорошо, когда ядер много и можно всем раздать, но как быть, если процессорные ресурсы делятся между несколькими контейнерами. В этом случае следует настроить лимиты. Как мы помним, процессорное время выделяется процессам порциями – тиками. Если тиков всем не хватает – собирается очередь.

Это ведет к росту LA, значение LA в 1 на ядро означает, что свободных тиков нет, а значение более единицы указывает на наличие очереди.

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

lxc.cgroup2.cpu.shares: 512


Число 512 указывает приоритет, он может принимать значение от 1 до 1024, значение по умолчанию – 1024. Таким образом контейнер со значением 512 в случае возникновения конкуренции за ресурсы получит в два раза меньше тиков, чем контейнер без этой настройки.

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

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

lxc.cgroup2.cpu.max: 50000 100000


Числа означают следующее: максимальное время использования ЦПУ, период в течении которого применяется ограничение в микросекундах. В приведенном примере мы выделили контейнеру половину процессорного ресурса. И он не сможет никогда его превысить, даже если процессор полностью простаивает.

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

Это позволяет обеспечить гарантированную производительность критичным сервисам.

lxc.cgroup2.cpuset.cpu_exclusive = 1


Этот параметр нужно обязательно сочетать с

lxc.cgroup2.cpuset.cpus = 0-3


При этом мы можем выделить контейнеру большее количество ядер, скажем 8, но в эксклюзивное использование ему перейдут только 4, а за остальные он будет конкурировать с другими контейнерами.
👍223🤡1
Установка сервера 1C:Предприятие, PostgreSQL и Apache2 на РЕД ОС 8

Тема установки сервера 1С:Предприятие на российские ОС остается достаточно актуальной и востребованной среди читателей.

РЕД ОС является одной из самых популярных систем для импортозамещения, но несмотря на отличную документацию с установкой сервера 1С у многих возникают сложности.

Поэтому мы самостоятельно изучили данный вопрос и подготовили практическую инструкцию с учетом всех особенностей и подводных камней РЕД ОС 8.

РЕД ОС "Сервер" согласно лицензионному соглашению может быть бесплатно использован физическими лицами для некоммерческого использования или юридическим для тестирования и изучения, в остальных случаях вам потребуется купить лицензию.

Также вам потребуется лицензия на сервер 1С:Предприятие или Сервер МИНИ на 5 подключений, лицензию для разработчика на сервер без графического окружения установить не удастся.

Сборка PostgreSQL для 1С включенная в состав дистрибутива предоставляется бесплатно.

Все команды, если не указано иное, выполняются с правами суперпользователя.

Читать далее: https://interface31.ru/post/ustanovka-servera-1cpredpriyatiya-postgresql-apache2-redos-8/
👍221🔥1
Тонкие настройки LXC. Монтирование

Еще одна часто встречающаяся задача – обмен файлами между контейнером и хостом, особенно когда надо передать большие объемы данных и сеть для этого не очень подходит.

Для этого можно воспользоваться монтированием, попробуем смонтировать файл с хоста в контейнер, это может быть архив с дистрибутивом некоторого ПО. Для этого в конфигурационный файл /etc/pve/lxc/nnn.conf (где nnn – ID контейнера) добавим:

lxc.mount.entry = /home/file1.tgz home/file1.tgz none bind,optional,create=file


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

Далее коротко пройдемся по опциям:

▫️none – тип файловой системы, в данном случае мы монтируем не ФС, а файл (аналогично и директориями).

▫️ bind – указывает на связывание, мы явно связываем файл в контейнере с файлом на хосте.

▫️ optional - необязательность монтирования, если файл на хосте отсутствует монтирование произведено не будет, блокировки загрузки контейнера не произойдет.

▫️ create – создать объект указанного типа (файл) в контейнере при его отсутствии.

Теперь примонтируем директорию, это также просто:

lxc.mount.entry = /home/dir1 home none bind,optional ,create=dir


А вот задача посложнее – смонтируем LVM раздел с файловой системой ext4:

lxc.mount.entry = /dev/mapper/ lvm-vg-myvolume1 home/myvolume1 ext4 defaults 0 0


Здесь мы вместо none указываем явно тип файловой системы и параметры монтирования также как мы это делаем в fstab.

А если нам нужно монтировать раздел блочного устройства, допустим у нас есть /dev/sda3 с типом файловой системы XFS. Здесь нам потребуется уже две строки:

lxc.mount.entry = /dev/sda3 home/volume3 xfs defaults 0 0
lxc.cgroup.devices.allow = b 8:3 rwm


Вторая строка разрешает доступ к устройству, где b 8:3 rwm означает:

▫️ b – блочное устройство

▫️ 8:3 – номер устройства, можно узнать командной ls -l /dev/sda3

▫️ rwm – набор прав: чтение, запись, создание специальных файлов устройства.

А теперь к несколько неожиданному, как мы помним в Linux все есть файл и если мы хотим поднять в контейнере сервис, который создает собственные сетевые устройства, скажем OpenVPN или WireGuard, то мы должны предоставить этим устройствам связь с внешним миром через хост. А для этого снова используем монтирование:

lxc.mount.entry: /dev/net dev/net none bind,create=dir
lxc.cgroup2.devices.allow: c 10:200 rwm


Мы смонтировали при помощи связывания специальную директорию /dev/net хоста в контейнер и выдали на нее права второй строкой. Единственное отличие с вместо b так как устройство у нас не блочное, а символьное.

Теперь мы можем создавать в контейнере собственные сетевые интерфейсы и они получат доступ во внешний мир через сетевую систему хоста.
1👍17
Текущее состояние альтернативных графических оболочек Linux

Когда мы говорим о графических оболочках рабочего стола Linux, то чаще всего на ум приходят GNOMЕ или KDE – оболочки первого эшелона, хотя список доступных вариантов ими не исчерпывается.

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

🔸 XFCE – основная альтернативная оболочка с более скромными системными требованиями. Разработка ведется силами небольшой, но слаженной команды. Релизный цикл консервативен, архитектура предсказуема.

Внешний вид строго следует парадигме начала 2000-х и на текущий момент является существенно устаревшим, при установке современных тем и икон-паков можно придать системе актуальный вид, но визуальной целостности она все равно не достигает.

Технически поддерживается целочисленное масштабирование, дробное масштабирование приводит к размытию шрифтов и падению производительности. Поддержка Wayland находится в стадии активного перехода и пока является экспериментальной.

🔸 MATE – возник как форк GNOME 2 и долгое время придерживался классической концепции этого окружения. В настоящий момент проект испытывает недостаток активных участников, а разработка фактически заморожена.

Визуально следует парадигме GNOME 2 и несмотря на то, что с современными графическими темами выглядит аккуратно, но визуально все-таки уступает современным графическим средам.

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

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

🔸 Cinnamon – флагманская оболочка и главная визитная карточка Linux Mint, активно развивается при финансировании сообщества и спонсоров дистрибутива.

Визуально следует классической компоновке, но поддерживает все современные требования к графическому интерфейсу и во многом способна составить конкуренцию оболочкам первого эшелона.

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

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

🔸 LXQt образовался при слиянии LXDE и Razor-qt. Развивается силами компактного, но активного открытого сообщества. Последний ключевой архитектурный этап – полный перевод компонентов на кодовую базу Qt 6 — успешно завершен.

Визуально представляет минимальный утилитарный, в чем-то даже аскетичный классический дизайн 2000-х, но в этом и главная «фишка» этой графической среды. Но минимальный – не означает устаревший.

Благодаря переходу на Qt6 полностью работает как целочисленное, так и дробное масштабирование, поддержка 2K/4K экранов, что ставит эту рабочую среду выше основных конкурентов в лице XFCE или MATE.

Поддержка Wayland находится в полноценной рабочей готовности.
👍14🤔3🤮2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤮3
Настраиваем локальный DNS-резольвер Unbound с поддержкой DNS-over-TLS (DoT)

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

Сегодня этот недостаток критичен: пассивный наблюдатель может отследить всю вашу интернет-активность, а активный злоумышленник - подменить ответы сервера и перенаправить вас на фишинговый сайт.

Чтобы обезопасить себя, настроим локальный DNS-резольвер, который будет обращаться к вышестоящим серверам по защищенному протоколу DNS-over-TLS.

Unbound - это свободный DNS‑сервер с открытым исходным кодом, который может работать в режиме валидирующего, рекурсивного и кеширующего резольвера.

Его разработку ведет компания NLnet Labs и распространяет его под лицензией BSD, в данной статье мы рассмотрим его установку и настройку на современные системы Debian или Ubuntu.

Читать далее: https://interface31.ru/post/nastraivaem-lokalnyj-dns-rezolver-unbound-s-podderzhkoj-dns-over-tls/
1👍19🔥113
С днем знаний!

Наша отрасль – это непрерывное обучение. Чуть остановился – и ты уже приотстал, сел посидел – и вот уже плетешься где-то далеко позади.

Как сказал Льюис Кэрролл: «Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!»

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

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

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

С одной стороны, учиться сегодня легко. Есть интернет, есть множество курсов на любой уровень подготовки и кошелек. С другой, существует заблуждение насчет доступности знаний, мол будет нужно – найду.

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

К сожалению, мы с подобными ситуациями сталкивались не раз. Как сталкивались и с фрагментарным уровнем знаний, когда коллега вроде бы знает все в части практической эксплуатации, но стоит сделать шаг в сторону – и все, приплыли.

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

Еще раз с праздником! Давайте не забывать учиться!
👍13🫡91
Проверяем DNS-записи при помощи PowerShell

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

Для разрешения доменных имен в PowerShell есть командлет Resolve-DnsName, использовать его достаточно просто, полный синтаксис команды выглядит так:

Resolve-DnsName -Name "example.com"


Но его можно упростить:

Resolve-DnsName example.com


Ответ зависит от типа записи, для A вы просто получите адрес, а для CNAME результатом будет доменное имя, на которое ссылается запись. Ниже будет приведена информация о полученном доменном имени и разрешение его в IP-адрес.

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

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

Для получения записей других типов дополнительно используйте ключ:

Resolve-DnsName example.com -Type MX


Результатом вывода для MX, если записи настроены правильно, вы получите одно или несколько доменных имен. Их разрешение в IP-адреса будет приведено ниже в выводе.

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

Resolve-DnsName example.com -Type MX -Server 8.8.8.8


А теперь несколько полезных опций, которые могут пригодиться при диагностике и разрешении проблем:

Resolve-DnsName example.com -DnsOnly


Данный ключ предписывает выполнить DNS-запрос игнорируя файлы hosts, локальный кеш, широковещательные протоколы и т.д.

Resolve-DnsName example.com -CacheOnly


Наоборот, выдаст запрос из локального кеша, что полезно для диагностики, если есть подозрения на неверную работу кеша.

Resolve-DnsName example.com -NoHostsFile


Указанный ключ проигнорирует локальный файл hosts, его следует использовать если есть подозрение, что указанный домен переназначен локально.

Это далеко не все возможности командлета, а только самые полезные. Больше информации вы можете найти в документации:

https://learn.microsoft.com/en-us/powershell/module/dnsclient/resolve-dnsname?view=windowsserver2022-ps
👍203🤔3🔥1
Simply Linux 11 - лед тронулся?

Simply Linux - отдельная операционная система от "Базальт СПО" на платформе Альт, которая позиционируется как бесплатная ОС для всех, что делает ее достаточно интересной.

От своих более именитых коммерческих сестер она отличается только отсутствием в Едином реестре российских программ, но базируется на общей с Рабочими станциями стабильной платформе p11 и предоставляет равные с ними возможности.

Прошлые выпуски Simply Linux позиционировались более как домашняя система, что вызывало некоторое недоумения, сегодня акцент сместился на бесплатную систему для всех, включая коммерческих пользователей.

И это правильный ход, потому как физические лица могут бесплатно использовать для личных, не связанных с предпринимательской деятельностью целей любую настольную систему Альт и их выбор будет скорее всего на стороне Рабочих станций, предоставляющих передовые выпуски GNOME или KDE, нежели остановится на Simply Linux со скромным XFCE.

Читать далее: https://interface31.ru/post/simply-linux-11-led-tronulsya/
👍143👎3🔥2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍231
Я календарь переверну…

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

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

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

На самом деле очень просто, добавляем к условию срабатывания:

and time() >= 094500 and time() <= 221500


В данном случае триггер будет срабатывать между 09:45 и 22:15, в остальное время тревожить он вас не будет.

Но оказалось, что триггер работает неправильно.

Первое, о чем тут хочется спросить – часовой пояс.

Да, с часовым поясом все нормально, Zabbix показывает события точно по времени, а вот триггер по времени работать не хочет.

А теперь вспоминаем, что веб-интерфейс Zabbix – это отдельное приложение, которое имеет собственные настройки часового пояса, в то время, как сама система хранит все события с временной меткой UTC.

И вот здесь важно понимать, что аппаратные часы Linux идут в UTC, а уже потом система или отдельные приложения делают поправку на свой часовой пояс.

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

Сам же сервер Zabbix работает в часовом поясе операционной системы, на которой запущен, и что там установлено в веб-интерфейсе, его волнует мало.

Таким образом у нашего коллеги оказалось, что веб-интерфейс Zabbix имел правильные настройки пояса – MSK (UTC +3), а вот сам сервер работал, как и был из коробки – т.е. в UTC.

Поэтому события в интерфейсе показывались с правильным временем, а вот триггеры срабатывали с отставанием на 3 часа, потому как считали, что сервер находится в часовом поясе UTC (Гринвич).

Ошибка эта распространенная, можно сказать – типовая. Поэтому никогда не забывайте настраивать правильный часовой пояс в самой ОС, причем сразу после установки. Также как и рабочую локаль. Избежите многих потенциальных сложностей.
🔥16👍42👀2🥱1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍273
Врут все

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

Согласен, но можно ли полностью доверять людям и всегда ли они говорят правду? Вопрос сложный и очень интересный. Потому что если ИИ врет не со зла, а потому что так сделана модель, то человек может умышленно искажать картину происходящего.

И что будет если одно наложится на другое? А ничего хорошего и как раз такой случай произошел сегодня утром. В одной подопечной организации админ с помощником наглухо убили кластер PostgreSQL в достаточно простой, можно сказать – штатной ситуации.

Как это водится, тестовый контур собран из говна и палок. Нагрузили тестами, поняли, что это надолго. Ну и нажали Reset на корпусе, после чего контейнер с PostgreSQL подниматься отказался, точнее не сам контейнер, а СУБД в нем.

Кого позовем на помощь? Правильно – ИИ, а этом случае это был Google Gemini PRO, по халявному аккаунту.

И вместе с ИИ они кластер качественно развалили, полностью, под ноль. А когда поняли, что Бобик издох и реанимации не подлежит – то покаялись, кивая в сторону ИИ, мол это не мы, начальника, это тупой ИИ нам посоветовал.

Ну что тут сказать, бывает. Но что-то подсказало мне пойти и почитать тот самый чат. А там открылось очень много интересного. Та самая «тупая» ИИ достаточно долго пыталась выяснить, а что же произошло в момент ребута.

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

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

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

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

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

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

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

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

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

Я понимаю, в корпоративном мире все привыкли врать, недоговаривать, искажать факты, но хотя бы ИИ не врите. Ему все равно, что получил на вход – то направит на выход, а вам потом с этим жить.
👍18🤷‍♂7🤣7🤡3👨‍💻3
Конкатенация в Windows и Linux

Многие знают команду cat, которая чаще всего используется для чтения файлов, и могут удивляться ее названию, недоумевая – причем тут кошки.

На самом деле команда cat выполняет конкатенацию – т.е. соединение текстовых строк.

Допустим нам надо объединить два текстовых файла. Самый простой вариант:

cat two.txt >> one.txt


После чего содержимое второго файла будет добавлено в конец первого. Но здесь мы использовали только перенаправление, а cat просто прочитал второй файл.

А если нужно наоборот, сначала содержимое второго файла, а потом первого?

В этом случае нам как раз потребуется конкатенация с перенаправлением результата в новый файл:

cat two.txt one.txt >> result.txt


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

Говоря о платформе Windows на ум сразу приходит PowerShell, но, вопреки мнению о скудости и убогости, CMD тоже есть что нам предложить.

Практически полным аналогом команды cat в CMD является type.

И это не «тип» как вы могли подумать, а «тайп», глагол имеющий значение «печатать», сразу можно вспомнить «телетайп».

Те же самые команды будут выглядеть как:

type two.txt >> one.txt
type two.txt one.txt >> result.txt


И да, перенаправление в Windows тоже есть и было с незапамятных времен.

При этом работа и cat и type имеет свою особенность, они предполагают, что файл должен заканчиваться последовательностью EOF (End of File) ну или содержать в конце символ переноса строки.

Иначе вместо ожидаемого результата:

строка_файла_1
строка_файла_2


Вы можете получить и получите:

строка_файла_1строка_файла_2 


В Linux это обычно не составляет проблемы, все текстовые редакторы, хоть консольные, хоть графические корректно завершают файл. А вот тот же Блокнот способен доставить проблем.

Ну и наконец PowerShell, для этого у него имеется специальный командлет Get-Content. А так как PowerShell имеет объектную модель, то результатом его работы будет набор объектов, каждый из которых будет содержать строку исходного файла.

Чтобы прочитать содержимое файла выполните:

Get-Content -Path one.txt


Но можно написать проще:

Get-Content one.txt


Если нужно выполнить конкатенацию, то перечислите нужные файлы через запятую.

В PowerShell указанные выше команды будут выглядеть так:

Get-Content two.txt >> one.txt
Get-Content two.txt, one.txt >> result.txt


А так как PowerShell возвращает нам набор объектов по одному на строку, то для него не имеет значения завершается ли файл EOF или нет. Результат всегда будет ожидаем.
👍141
Вечер ностальгических воспоминаний.

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

А оказывается с тех пор прошло уже больше 25 лет.

Статья хорошая, даже сейчас интересная.
👍22😢71