12 февраля в 06:36

UNIX-подобные системы содержат кучу костылей. Крах «философии UNIX»

UPD от 2017-03-04: кто-то выполнил английский перевод. Обсуждение на Hacker News.

В первой части статьи перечислю кучу костылей UNIX, и вообще разных недостатков. Во второй — про «философию UNIX». Статья написана наскоро, «полировать» дальше не хочу, скажите спасибо, что написал. Поэтому многие факты привожу без ссылок.

Костыли в UNIX начали возникать ещё с момента появления UNIX, а это было ещё раньше появления не только Windows, но даже вроде бы Microsoft DOS (вроде бы, мне лень проверять, проверяйте сами). Если лень читать, хотя бы просмотрите все пункты, что-нибудь интересное найдёте. Это далеко не полный список, это просто те косяки, который я захотел упомянуть.

  • В самом начале make был программой, которую один человек написал для себя и нескольких своих знакомых. Тогда он, недолго думая, сделал так, что командами воспринимаются строки, которые начинаются с Tab. Т. е. Tab воспринимался отлично от пробела, что крайне некрасиво и нетипично ни для UNIX, ни за его пределами. Он так сделал, потому что не думал, что make будет ещё кто-то использовать кроме этой небольшой группы. Потом появилась мысль, что make — хорошая вещь и неплохо бы включить его в стандартный комплект UNIX. И тогда чтобы не сломать уже написанные мейкфайлы, т. е. написанные вот этими вот десятью людьми, он не стал ничего менять. Ну вот так и живём… Из-за тех десятерых страдаем мы все.

  • Почти в самом начале в UNIX не было папки /usr. Все бинарники размещались в /bin и /sbin. Но потом вся инфа перестала помещаться на тот диск, который был в распоряжении авторов UNIX (Томпсон, Ритчи). Поэтому они достали ещё один диск, создали папку /usr, а в ней — ещё один bin и ещё один sbin. И смонтировали новый диск в /usr. Оттуда и пошло. Так появилась «вторая иерархия» /usr, а потом в какой-то момент ещё и «третья иерархия» /usr/local, а потом ещё и /opt. Как пишет рассказчик этой истории: «Не удивлюсь, если когда-нибудь ещё появится /opt/local». UPD от 2017-02-12: я нашёл ссылку, где я почерпнул эту историю. Читайте, там более точная версия произошедшего.

  • sbin изначально означало «static bin», а не «superuser bin», как можно было бы подумать. И содержал sbin статические бинарники. Но потом sbin стал содержать динамические бинарники, его название потеряло смысл.

  • Windows часто ругают за наличие реестра и сообщают при этом, что подход UNIX-подобных систем (куча конфигов) якобы лучше. А между прочим однажды в ext4 появилась особенность (является ли это багом, вопрос спорный), из-за которой при резком выключении компа Gnome потерял все свои конфиги в рабочей папке юзера. И разработчик этой ext4 сказал в обсуждении баг репорта, что Gnome'у надо было использовать что-то вроде реестра для хранения инфы.

    UPD от 2017-02-12: источники: раз и два. Имя отписавшегося maintainer'а ext4: Theodore Ts'o. Вот его слова:

    If you really care about making sure something is on disk, you have to use fsync or fdatasync. If you are about the performance overhead of fsync(), fdatasync() is much less heavyweight, if you can arrange to make sure that the size of the file doesn't change often. You can do that via a binary database, that is grown in chunks, and rarely truncated.

    I'll note that I use the GNOME desktop (which means the gnome panel, but I'm not a very major desktop user), and «find .[a-zA-Z]* -mtime 0» doesn't show a large number of files. I'm guessing it's certain badly written applications which are creating the «hundreds of dot files» that people are reporting become zero lengh, and if they are seeing it happen a lot, it must be because the dot files are getting updated very frequently. I don't know what the bad applications are, but the people who complained about large number of state files disappearing should check into which application were involved, and try to figure out how often they are getting modified. As I said, if large number of files are getting frequently modified, it's going to be bad for SSD's as well, there are multiple reasons to fix badly written applications, even if 2.6.30 will have a fix for the most common cases. (Although some server folks may mount with a flag to disable it, since it will cost performance.)

    И это не говоря уж о том, что критичные файлы UNIX (такие как /etc/passwd), который читаются при каждом (!) вызове, скажем, ls -l, записаны в виде простого текста. И эти файлы надо заново читать и заново парсить при каждом вызове ls -l! Было бы гораздо лучше использовать бинарный формат. Или БД. Или некий аналог реестра. Как минимум, для вот таких вот критичных для производительности ОС файлов.

  • Two famous people, one from MIT and another from Berkeley (but working on Unix) once met to discuss operating system issues. The person from MIT was knowledgeable about ITS (the MIT AI Lab operating system) and had been reading the Unix sources. He was interested in how Unix solved the PC loser-ing problem. The PC loser-ing problem occurs when a user program invokes a system routine to perform a lengthy operation that might have significant state, such as IO buffers. If an interrupt occurs during the operation, the state of the user program must be saved. Because the invocation of the system routine is usually a single instruction, the PC of the user program does not adequately capture the state of the process. The system routine must either back out or press forward. The right thing is to back out and restore the user program PC to the instruction that invoked the system routine so that resumption of the user program after the interrupt, for example, re-enters the system routine. It is called «PC loser-ing» because the PC is being coerced into «loser mode,» where «loser» is the affectionate name for «user» at MIT.

    The MIT guy did not see any code that handled this case and asked the New Jersey guy how the problem was handled. The New Jersey guy said that the Unix folks were aware of the problem, but the solution was for the system routine to always finish, but sometimes an error code would be returned that signaled that the system routine had failed to complete its action. A correct user program, then, had to check the error code to determine whether to simply try the system routine again. The MIT guy did not like this solution because it was not the right thing.

    The Rise of «Worse is Better» By Richard Gabriel

    Если кратко и своими словами, то в начале разработки UNIX авторы UNIX решили попросту выдавать ошибку из ядра пользовательской программе, если пользовательская программа прервана по сигналу, и на этот сигнал повешен обработчик. Иными словами, если вы перехватили Ctrl-C (т. е. поставили на него обработчик) в своей программе, а юзер за терминалом нажал этот самый Ctrl-C, то ОС выполнит обработчик, а потом вместо простого продолжения того сисвызова, который выполнялся в момент Ctrl-C, просто прервёт его, вернув из ядра в пользовательскую программу EINTR. В результате программисту, пишущему эту программу придётся эту EINTR предусмотреть. А это усложняет этот userspace код. Ценой упрощения кода ядра. Да, нужно было сделать по-другому. Усложнить код ядра и упростить userspace код, который придётся писать всем программистам. Но тому человеку из Беркли из цитаты выше было пофигу. Он фактически сказал: «Да мне пофиг, что все будут страдать, главное, чтоб код ядра попроще был».

    Дальше — больше. Позже в UNIX-системах всё же пофиксили упомянутую особенность, добавив так называемый SA_RESTART. То есть вместо того, чтобы просто всё пофиксить, они добавили специальный флаг. Так мало того, что они это сделали, этот SA_RESTART ещё и не всегда работает! В частности, в GNU/Linux select, poll, nanosleep и др. не продолжают свою работу после перехваченного прерывания даже в случае SA_RESTART!

  • Вообще, конкретные обстоятельства, возникшие во время разработки оригинальной UNIX, сильно оказали на неё влияние. Скажем, читал где-то, что команда cp названа именно так, а не copy, потому что UNIX разрабатывали с использованием терминалов, которые очень медленно выдавали буквы. А потому набрать cp было быстрее, чем copy. UPD от 2017-02-12: найти именно ту ссылку, которую я видел когда-то давно, и в которой приводился пример с cp и copy, мне не удалось. Но есть, например, вот эта ссылка.

    Commands — Are These Real Words?

    The basic AIX commands (and all UNIX system commands) are, for the most
    part, very short, cryptic, two-letter command names. Imagine back years ago,
    when computers had only very slow teletype keyboards and paper “displays.”
    (Some of us aren’t imagining, we’re remembering!) Imagine also, people who
    didn’t like typing long commands because there was such a long delay between
    commands and the computer response. If there were any mistakes, the user had
    to retype the whole thing (especially aggravating for folks that type with only
    two fingers!).

    Also, some UNIX commands came from university students and researchers who
    weren’t bound by usability standards (no rules, merely peer pressure). They
    could write a very useful, clever command and name it anything—their own initials,
    for example (awk by Aho, Weinberger, and Kernighan), or an acronym
    (yacc, Yet Another Compiler-Compiler).

  • Вообще, названия утилит UNIX — это отдельная история. Скажем, название grep идёт от командй g/re/p в текстовом редакторе ed. (Ну а cat — от concatenation, я надеюсь, это все и так знали :) Ну и для кучи: vmlinuz — gZipped LINUx with Virtual Memory support).

  • printf внезапно является далеко не самым быстрым способом вывода информации на экран или в файл. Не знали, да? А дело в том, что printf, как и сама UNIX в целом, был придуман не для оптимизации времени, а для оптимизации памяти. printf каждый раз парсит в рантайме строку формата. Именно поэтому в веб сервере H2O был придуман специальный препроцессор, который переносит парсинг строки формата на этап компиляции.

    UPD от 2017-02-12: источник.

  • Когда Кена Томпсона, автора UNIX (вместе с Деннисом Ритчи) спросили, что бы он поменял в UNIX, он сказал, что назвал бы функцию creat (sic!) как create. UPD от 2017-02-12: источников полно, например этот. No comments. Замечу, что позже этот же Кен Томпсон вместе с другими разработчиками оригинальной UNIX создал систему Plan 9, исправляющую многие недостатки UNIX. И в ней эта функция называется create :) Он смог :)

  • Ещё одна цитата:

    A child which dies but is never waited for is not really gone in that it still consumes disk swap and system table space. This can make it impossible to create new processes. The bug can be noticed whenseveral & separators are given to the shell not followed by ancommand without an ampersand. Ordinarily things clean themselves upwhen an ordinary command is typed, but it is possible to get into asituation in which no commands are accepted, so no waits are done;the system is then hung.The fix, probably, is to have a new kind of fork which creates aprocess for which no wait is necessary (or possible); also to limit the number of active or inactive descendants allowed to a process.

    Источник

    Это цитата из очень раннего манула UNIX. Уже тогда существование зомби-процессов признавалось багом. Но потом на этот баг попросту забили. Понятное дело, что гораздо позже эта проблема всё же была решена. Т. е. в современном GNU/Linux инструменты для убивания зомби-процессов всё же существуют. Но о них мало кто знает. Обычном kill'ом зомби не убиваются. Про существование зомби-процессов все говорят: «It's for design».

  • Ещё немного про уже упомянутый язык C. Вообще язык C разрабатывался одновременно с UNIX, поэтому критикуя UNIX, нужно покритиковать и C тоже. То, что C очень плох, написано много, я не буду повторять все эти аргументы. Там, синтаксис типов плохой, препроцессор ужасен, легко выстрелить себе в ногу, всякие 4["string"], всякие sizeof ('a') != sizeof (char) (в C, не в C++!), всякие i++ + ++i, всякие while (*p++ = *q++) ; (пример из Страуструпа, второе дополненное издание) и так далее и тому подобное.

    Скажу лишь вот что. В C до сих пор не научились удобно работать со строками. Неудобство работы со строками постоянно приводит к разнообразным проблемам безопасности. И эту проблему до сих пор не решили! Вот относительно свежий документ от комитета C. В нём обсуждается весьма сомнительный способ решения проблемы со строками. И делается вывод, что этот способ плох. Год публикации: 2015. То есть даже к 2015-му году окончательного решения ещё нет!

    И это не говоря об отсутствии простой, удобной и мультиплатформенной системы сборки (а не этого монстра autotools, который ещё и не поддерживает винду, и другого монстра cmake, который поддерживает винду, но всё равно монстр), стандартного менеджера пакетов, удобного как npm (js) или cargo (rust), нормальной portability library, с помощью которой можно было кроссплатформенно хотя бы прочитать содержимое папки и хотя бы даже главного сайта C, который был бы главной точкой входа для всех новичков и содержал бы в себе не только документацию, но и краткую инструкцию по установке инструментов C на любую платформу, по созданию простого проекта на C, а также содержал бы удобный поиск по пакетам C (которые должны быть размещены в стандартном репозитории) и, главное, был бы точкой сбора user community. Я даже зарегал домен c-language.org в надежде, что когда-нибудь я создам там такой сайт. Эх, мечты, мечты. (У меня ещё cpp-language.org заныкан, бугога :)) Но всего этого нет. Хоть это и есть у всех популярных языков, кроме C и C++. И даже у Haskell всё это есть. И у Rust.

    У Rust, у этого выскочки, который, кстати говоря, метит в ту же нишу, что и C. Есть единый конфиг, который одновременно является конфигом проекта, конфигом сборки и конфигом для менеджера пакетов (собственно, cargo — это менеджер проектов и система сборки одновременно). Есть возможность указания в качестве зависимости для данного пакета другого пакета, размещённого где-то в *GIT*, в том числе указание в качестве зависимости напрямую программы на *GITHUB*. Генерация из коробки документации из сорцов, записанной в комментах на *MARKDOWN*. И пакетный менеджер, использующий для версий *SEMVER*. Итак, *GIT*, *GITHUB*, *MARKDOWN*, *SEMVER*, короче говоря *BUZZWORDS*, *BUZZWORDS* и ещё раз *HIPSTERS' BUZZWORDS*. И всё сразу из коробки. Прямо вот заходишь на их главный сайт, и вот на тебе на блюдечке с голубой каёмочкой. И работает всё одинаково на всех платформах. Несмотря на то, что Rust — это вроде как язык системного программирования, а не какой-нибудь там javascript. Несмотря на то, что в Rust можно байты гонять. И арифметика указателей там есть. Так почему же у них, у этих выскочек-растовцев, эти хипстерские баззворды есть, а у нас, сишников, их нет? Обыдно.

    Я помню, один знакомый спрашивает у меня, где посмотреть список пакетов для C/C++. Пришлось сказать ему, что такого единого места нет. Он: «Программисты на C/C++ должны страдать?» Мне нечего было ему ответить.

    Ах да, забыл ещё одну вещь. Посмотрите, пожалуйста, на прототип функции signal в том виде, в котором он дан в стандарте C: void (*signal(int sig, void (*func)(int)))(int); и попытайтесь его понять.

  • Терминал в UNIX — жуткое legacy.

  • Имена файлов в файловых системах UNIX (ext2 и пр.) есть просто поток байтов без кодировки. В какой кодировке они будут интерпретированы, зависит от локали. То есть если создать файл на ОС в одной локали, а потом пытаться посмотреть его имя в ОС в другой локали, будет плохо. В виндовом NTFS такой проблемы нет.

  • UNIX shell хуже PHP! Да, да, а вы что, не знали? Сейчас модно ругать PHP. Но ведь UNIX shell ещё хуже :) Особенно плохим он становиться, если пытаться на нём программировать, ведь полноценным языком программирования он не является. Но даже для своей ниши (скриптинг типичных задач по администрированию) он годится плохо. Виной тому примитивность shell, непродуманность, legacy, куча частных случаев, костылей, бардак с кавычками, бекслешами, специальными символами и повёрнутость shell'а (как и всего UNIX) на простом тексте.

    • Начнём с затравки. Как рекурсивно найти в папке foo все файлы с именем \? Правильный ответ таков: find foo -name '\\'. Ну или так: find foo -name \\\\. Последний вариант вызовет особенно много вопросов. Попробуйте объяснить человеку, плохо разбираемущемуся в UNIX shell, почему здесь нужно именно четыре бекслеша, а не два и не восемь (грамотеи, подскажите, как правильно написать это предложение, пишите в личку). А написать здесь нужно четыре бекслеша, потому что UNIX shell делает backslash expanding, и find тоже его делает.

    • Как touch'нуть все файлы в папке foo (и во вложенных)? На первый взгляд, один из способ таков: find foo | while read A; do touch $A; done. Ну, на первый взгляд. На самом деле здесь можно придумать аж 5 нюансов, которые могут испортить нам малину (и привести к проблемам с безопасностью):

      • Имя файла может содержать бекслеш, поэтому нужно писать не read A, а read -r A.
      • Имя файла может содержать пробел, поэтому нужно писать не touch $A, а touch "$A".
      • Имя файла может не только содержать пробел, но и начинаться с пробела, поэтому нужно писать не read -r A, а IFS="" read -r A.
      • Имя файла может содержать перевод строки, поэтому вместо find foo нужно использовать find foo -print0, а вместо IFS="" read -r A нужно использовать IFS="" read -rd "" A (тут я не совсем уверен).
      • Имя файла может начинаться с дефиса, поэтому вместо touch "$A" нужно писать touch -- "$A".

      Итоговый вариант выглядит так: find foo -print0 | while IFS="" read -rd "" A; do touch -- "$A"; done. Круто, да? И здесь мы, кстати, не учли, что POSIX не гарантирует (я не совсем в этом уверен), что touch поддерживает опцию --. Если учитывать ещё и это, то придётся для каждого файла проверять, что он начинается с дефиса (или что не начинается со слеша) и добавлять в начало ./. Теперь вы поняли, почему скрипты configure, генерируемые autoconf'ом такие большие и трудночитаемые? Потому что этому configure нужно учитывать всю эту муть, включая совместимость с разными shell'ами. (В данном примере для демонстрации я использовал решение с пайпом и циклом. Можно было использовать решение с -exec или xargs, но это было бы не так эффектно). (Ладно, хорошо, мы знаем, что имя файла начинается с foo, поэтому оно не может начинаться с пробела или дефиса).

    • В переменной A лежит имя файла, нужно удалить его на хосте a@a. Как это сделать? Может быть так: ssh a@a rm -- "$A" (как вы уже заметили, мы тут уже учли, что имя файла может содержать пробелы и начинаться с дефиса)? Ни в коем случае! ssh — это вам не chroot, не setsid, не nohup, не sudo и не какая-нибудь ещё команда, которая получает exec-команду (т. е. команду для непосредственной передачи сисвызовам семейства execve). ssh (как и su) принимает shell-команду, т. е. команду для обработки shell'ом (термины exec-команда и shell-команда — мои). ssh соединяет все аргументы в строку, передаёт строку на удалённую сторону и там выполняет shell'ом. Окей, может быть так: ssh a@a 'rm -- "$A"'? Нет, эта команда попытается найти переменную A на удалённой стороне. А её там нет, потому что переменные через ssh не передаются. Может, так: ssh a@a "rm -- '$A'"? Нет, это не сработает, если имя файла содержит одинарную кавычку. В общем, не буду вас мучать, правильный ответ таков: ssh a@a "rm -- $(printf '%q\n' "$A")". Согласитесь, удобно?

    • Как зайти на хост a@a, с него — на b@b, с него — на c@c, с него — на d@d, а с него удалить файл /foo? Ну, это легко:

      ssh a@a "ssh b@b \"ssh c@c \\\"ssh d@d \\\\\\\"rm /foo\\\\\\\"\\\"\""
      

      Слишком много бекслешей, да? Ну, не нравится так, давайте чередовать одинарные и двойные кавычки, будет не так скучно:

      ssh a@a 'ssh b@b "ssh c@c '\''ssh d@d \"rm /foo\"'\''"'
      

      А между прочим, если бы вместо shell'а был Lisp, и там функция ssh передавала бы на удалённую сторону не строку (вот она, повёрнутось UNIX на тексте!), а уже распарсенный AST (abstract syntax tree), то такого ада бекслешей не было бы:

      (ssh "a@a" '(ssh "b@b" '(ssh "c@c" '(ssh "d@d" '(rm "foo")))))
      

      «А? Что? Lisp? Что за Lisp?» Интересно, да? На, читайте. И другие статьи Грэма. На русском тоже можно найти.

    • Совместим предыдущие два пункта. Имя файла лежит в переменной A. Нужно зайти на a@a, с него — на b@b, далее на c@c, d@d и удалить файл, лежащий в переменной A. Это я оставляю вам в качестве упражнения :) (Сам я не знаю, как это сделать :) Ну, может, придумаю, если подумаю).

    • echo вроде как предназначен, чтобы печатать на экран строки. Вот только использовать его для этой цели, если строчка чуть сложнее, чем «Hello, world!», нельзя. Единственно верный способ вывести произвольную строку (скажем, из переменной A) таков: printf '%s\n' "$A".

    • Допустим, нужно направить stdout и stderr команды cmd в /dev/null. Загадка: какие из этих шести команд выполняют поставленную задачу, а какие — нет?

      cmd > /dev/null 2>&1
      cmd 2>&1 > /dev/null
      { cmd > /dev/null; } 2>&1
      { cmd 2>&1; } > /dev/null
      ( cmd > /dev/null ) 2>&1
      ( cmd 2>&1 ) > /dev/null
      

      Оказывается, правильный ответ — 1-я, 4-я и 6-я выполняют, 2-я, 3-я и 5-я — не выполняют. Опять-таки, выяснение причин этого оставляется в качестве упражения :)

  • Вообще, этот пост появился в ответ на вот этот пост. Там говорилось, мол, в винде специальная дата используется как метка драйвера от Microsoft. Вместо ввода специального аттрибута или проверки производителя. Особенностей такого рода в UNIX полно. Является ли файл скрытым, выясняется на основе наличия точки в начале файла вместо специального аттрибута. Когда я сам впервые об этом узнал (да, да, в те далёкие времена, когда я впервые поставил Ubuntu), я был шокирован. Я подумал, вот идиоты. А сейчас привык. Но если вдуматься, это жуткий костыль. Далее, shell выясняет, является ли он login shell'ом на основе дефиса, переданного первым символом в argv[0] (?!). Это abuses (ну или misuses, неправильно использует, не знаю, как по-русски сказать) argv[0]. argv[0] не для этого предназначен. Вместо какого-нибудь другого способа. Любой другой способ был бы красивее. Как угодно, любым другим аргументом, переменной окружения.

  • В BSD sockets юзер вынужден сам менять порядок байт у номера порта. А всё потому, что когда-то давно кто-то допустил в коде ядра UNIX ошибку, не предусмотрев смену порядка байт. И в качестве временного хака исправил user space код вместо кода ядра. Так и живём. Оттуда это и в Windows перешло (вместе с файлом /etc/hosts, он же C:\windows\system32\drivers\etc\hosts).

    UPD от 2017-02-12: источник.

«Философия UNIX». Есть мнение, что якобы UNIX прекрасна и идеальна. Что все её основные идеи («всё есть файл», «всё есть текст» и т. д.) прекрасны и составляют так называемую прекрасную «философию UNIX». Так вот, как вы уже начали догадываться, это не совсем так. Давайте разберём эту «философию UNIX» по пунктам. Сразу скажу: я не хочу сказать, что все пункты нужно отменить, просто я указываю на их неуниверсальность.

  • «Всё есть текст». Как мы с вами уже выяснили на примере /etc/passwd, повсеместное использование простого текста может привести к проблемам с производительностью. И вообще, авторы UNIX фактически придумали для каждого системного конфига (passwd, fstab и так далее) свой формат. Со своими правилами экранирования специальных символов. Да, а вы что думали? /etc/fstab использует пробелы и переносы строк как разделители. Но что если имена папок содержат, скажем, пробелы? На этот случай формат fstab'а предусматривает специальное экранирование имён папок. Так что любой скрипт, читающий fstab, оказывается, должен это экранирование интерпретировать. Например, с помощью специально предназначенной для этого утилиты fstab-decode (запускать от рута). Не знали, да? Идите исправляйте свои скрипты :) В результате для каждого системного конфига нужен свой парсер. И было бы гораздо проще, если бы для системных конфигов использовался вместо этого какой-нибудь JSON или XML. А может быть даже некий бинарный формат. Особенно для тех конфигов, которые постоянно читаются разными программами. И для которых, как следствие, нужна хорошая скорость чтения (а у бинарных форматов она выше).

    Я не закончил по поводу «всё есть текст». Стандартные утилиты выдают вывод в виде простого текста. Для каждой утилиты фактически нужен свой парсер. Часто приходится парсить вывод той или иной утилиты при помощи sed, grep, awk и т. д. У каждой утилиты свои опции для того, чтобы установить, какие именно столбцы нужно выдавать, по каким столбцам нужно сортировать вывод и т. д. Было бы лучше, если бы утилиты выдавали вывод в виде XML, JSON, некоего бинарного формата или ещё чего-нибудь. А для удобного вывода этой информации на экран и для дальнейшей работы с ней можно было бы пайпить результат в дополнительные утилиты, которые убирают те или иные столбцы, сортируют по тому или иному столбцу, выбирают нужные строки и т. д. И либо выводят результат в виде красивой таблички на экран, либо передают его куда-то дальше. И всё это универсальным способом, не зависящим от исходной утилиты, которая сгенерировала вывод. И без необходимости парсить что-либо регексами. Да, UNIX shell плохо работает с JSON и XML. Но ведь у UNIX shell полно других недостатков. Нужно выкинуть его вовсе и заменить на некий другой язык, который помимо всего прочего может удобно работать со всякими JSON.

    Вы только представьте! Вот допустим, нужно удалить все файлы в текущей папке с размером, большим 1 килобайта. Да, я знаю, что такое надо делать find'ом. Но давайте предположим, что это нужно сделать непременно ls'ом (и без xargs). Как это сделать? Вот так: LC_ALL=C ls -l | while read -r MODE LINKS USER GROUP SIZE M D Y FILE; do if [ "$SIZE" -gt 1024 ]; then rm -- "$FILE"; fi; done. (LC_ALL здесь нужен был, чтобы быть уверенным, что дата будет занимать именно три слова в выводе ls). Мало того, что это решение выглядит некрасиво, оно ещё страдает рядом недостатков. Во-первых, оно не будет работать, если имя файла содержит перевод строки или начинается с пробела. Далее, нам нужно явно перечислить названия всех столбцов ls, ну или как минимум помнить, на каком месте находятся интересующие нас (т. е. SIZE и FILE). Если мы ошибёмся в порядке столбцов, то ошибка выяснится лишь на этапе выполнения. Когда мы удалим не те файлы :)

    А как бы выглядело решение в идеальном мире, который я предлагаю? Как-то так: ls | grep 'size > 1kb' | rm. Кратко, а главное смысл виден из кода, и невозможно ошибиться. Смотрите. ls в моём мире всегда выдаёт всю инфу. Специальня опция -l для этого не нужна. Если нужно убрать все столбцы и оставить только имя файла, то это делается специальной утилитой, в которую нужно направить вывод ls. Итак, ls выдаёт список файлов. В некоем структуированном виде, скажем, JSON. Это представление «знает» названия столбцов и их типы, т. е. что это, строка, число или что-то ещё. Далее этот вывод направляется в grep, который в моём мире выбирает нужные строки из этого JSON. JSON «знает» названия полей, поэтому grep «понимает», что здесь означает «size». Более того, JSON содержит инфу о типе поля size. Он содержит инфу о том, что это число, и даже что это не просто число, а размер файла. Поэтому можно сравнить его с 1kb. Далее grep направляет вывод в rm. rm «видит», что он получил файлы. Да, да, JSON ещё и хранит инфу о типе этих строк, о том, что это — файлы. И rm их удаляет. А ещё JSON отвечает за правильное экранирование специальных символов. Поэтому файлы со спецсимволами «просто работают». Круто? Идею я взял отсюда (там ещё есть ссылка на более подробный английский оригинал), посмотрите. Ещё замечу, что в Windows Powershell реализовано как раз что-то похожее на эту идею.

  • UNIX shell. Ещё одна базовая идея UNIX. Причём о мелких недостатках UNIX shell я уже поговорил в первой части статьи. Сейчас будут крупные. В чём «крутость» UNIX shell? В том, что на момент своего появления (это было очень давно) UNIX shell был гораздо мощнее командных интерпретаторов, встроенных в другие ОС. И позволял писать более мощные скрипты. Да и вообще, на момент своего появления UNIX shell был, видимо, самым мощным из скриптовых языков вообще. Потому что нормальных скриптовых языков, т. е. таких, которые бы позволяли полноценное программирование, а не только скриптинг, тогда, видимо, вообще не существовало. Это потом уже в один прекрасный день один программист по имени Larry Wall заметил, что UNIX shell всё-таки недостаёт до нормального языка программирования. И он захотел соединить краткость UNIX shell'а с возможностью полноценного программирования из C. И создал Perl. Да, Perl и другие последующие скриптовые языки программирования фактически заменили UNIX shell. Это константирует даже Роб Пайк, один из авторов (как я считаю) той самой «философии UNIX» (про него мы ещё поговорим). Вот здесь на вопрос об «одной утилите для одной вещи» он сказал: «Those days are dead and gone and the eulogy was delivered by Perl». Причём я считаю, что эта его фраза относилась к типичному использованию UNIX shell, т. е. к ситуации связывания большого количества маленьких утилит в shell-скрипте. Нет, говорит Пайк, просто используйте Perl.

    Я не закончил про UNIX shell. Рассмотрим ещё раз пример кода на shell, который я уже приводил: find foo -print0 | while IFS="" read -rd "" A; do touch -- "$A"; done. Здесь в цикле вызывается touch (да, я знаю, что этот код можно переписать на xargs, причём так, чтобы touch вызывался только один раз; но давайте пока забьём на это, хорошо?). В цикле вызывается touch! То есть для каждого файла будет запущен новый процесс! Это нереально неэффективно. Код на любом другом языке программирования будет работать быстрее этого. Просто на момент появления UNIX shell он был одним из немногих языков, которые позволяют написать это действие в одну строчку.

    Короче говоря, вместо UNIX shell нужно использовать любой другой скриптовый язык программирования. Который подходит не только для скриптинга, но и для реального программирования. Который не запускает новый процесс каждый раз, когда нужно «touch'нуть» файл. Возможно, понадобится «доложить» в этот скриптовый язык средства для простого выполнения вещей, которые есть в shell, скажем, для создания пайпов.

  • Простота. Здесь я говорю не конкретно про shell и про связывание кучи простых утилит из shell'а (про это был предыдущий пункт), а про простоту вообще. Использование простых инструментов. Скажем, редактирование картинки sed'ом. Да, да. Конвертим jpg в ppm при помощи командной строки. Затем при помощи графического редактора, grep, sed и такой-то матери редактируем картинку. А потом обратно в jpg. Да, так можно. Но часто photoshop'ом или gimp'ом всё-таки лучше. Хоть это и большие, интегрированные программы. Не в стиле UNIX.

На этом я закончу эти пункты. Да, хватит. Есть идеи в UNIX, которые мне реально нравятся. Скажем, «программа должна делать одну вещь и делать её хорошо». Но не в контексте shell. Вы уже поняли, что я не люблю shell. (Ещё раз повторю, я считаю, что в приведённом выше интервью Пайка он воспринял принцип «программа должна делать одну вещь и делать её хорошо» именно в контексте shell и потому отверг его). Нет, я говорю про этот принцип в своей сути. Скажем, консольный почтовый клиент не должен иметь встроенный текстовый редактор, он должен просто запустить некий внешний редактор. Или вот принцип, по которому нужно писать консольное ядро для программы и потом графическую оболочку для этого ядра.

Теперь общая картина. Однажды появился UNIX. На момент появления он был прорывом. И он был во многом лучше своих конкурентов. UNIX имел много идей. И, как и любая ОС, UNIX требовал от программистов соблюдения некоторых принципов при написании прикладных программ. Идеи, лежащие в основе UNIX, стали называться «философией UNIX». Одним из тех людей, которые сформулировали философию UNIX, был уже упомянутый Роб Пайк. Он это сделал в своей презентации «UNIX Style, or cat -v Considered Harmful». После презентации он вместе с Керниганом опубликовал статью по мотивам презентации. В ней авторы рассказали о том, что, скажем, предназначение cat — это только конкатенация и ничего больше (ну то есть «склеивание» файлов, мы с вами помним, как расшифровывается cat, так ведь?). Возможно, что это Пайк как раз и придумал «философию UNIX». В честь этой презентации был назван сайт cat-v.org, почитайте его, очень интересный сайт.

Но потом, через много лет, этот же Пайк сделал ещё две презентации, в которых, как я считаю, отменил свою философию обратно. Поняли, фанатики, да? Ваш кумир отказался от своей же философии. Можете расходиться по домам. В первой презентации «Systems Software Research is Irrelevant» Пайк сетует на то, что никто больше не пишет новых ОС. А даже если и пишут, то просто ещё один UNIX (который подразумевается в этой презентации уже чем-то неинтересным): «New operating systems today tend to be just ways of reimplementing Unix. If they have a novel architecture — and some do — the first thing to build is the Unix emulation layer. How can operating systems research be relevant when the resulting operating systems are all indistinguishable?»

Вторую презентацию Пайк прямо называет: «The Good, the Bad, and the Ugly: The Unix Legacy». Пайк говорит, что простой текст не универсален, он хорош, но работает не всегда: «What makes the system good at what it's good at is also what makes it bad at what it's bad at. Its strengths are also its weaknesses. A simple example: flat text files. Amazing expressive power, huge convenience, but serious problems in pushing past a prototype level of performance or packaging. Compare the famous spell pipeline with an interactive spell-checker». Далее: «C hasn't changed much since the 1970s… And — let's face it — it's ugly». Дальше Пайк признаёт ограниченность пайпов, соединяющих простые утилиты, ограниченность регексов.

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

Люди, стоящие у истоков UNIX, в определённый момент начали писать новую ОС: Plan 9. В том числе упомянутые Томпсон, Ритчи и Пайк. Учитывая многие ошибки UNIX. Но и Plan 9 никто не возводит в абсолют. В «Systems Software Research is Irrelevant» Пайк упоминает Plan 9, но несмотря на это всё равно призывает писать новые ОС.

James Hague, ветеран программирования (занимается программированием с восьмидесятых) пишет: «What I was trying to get across is that if you romanticize Unix, if you view it as a thing of perfection, then you lose your ability to imagine better alternatives and become blind to potentially dramatic shifts in thinking» (ссылка). Прочитайте эту статью и его же статью «Free Your Technical Aesthetic from the 1970s», на которую он ссылается. (Вообще, если вам понравилась моя статья, то и его блог тоже, наверное, понравится, погуляйте там по ссылкам).

Итак, я не хочу сказать, что UNIX — плохая система. Просто обращаю ваше внимание на то, что у неё есть полно недостатков, как и у других систем. И «философию UNIX» я не отменяю, просто обращаю внимание, что она не абсолют. Мой текст обращён скорее к фанатикам UNIX и GNU/Linux. Провокационный тон просто чтобы привлечь ваше внимание.

UPD от 2017-02-14: комментаторы указывают, что сравнивать UNIX shell с PHP некорректно. Конечно, некорректно! Потому что UNIX shell не претендует на то, чтобы быть полноценным языком программирования, он предназначен для скриптинга системы. Вот только я в одно время этого не знал. И вдобавок считал UNIX shell прекрасным. Вот для людей в таком же положении я всё это и говорю. Ещё как минимум один комментатор говорит, что сравнивать UNIX shell нужно с cmd. Я бы сказал, что сравнивать надо с Windows Powershell. Последний, как я уже говорил, в чём-то превосходит UNIX shell.

UPD от 2017-02-14: мне понравился вот этот коммент от sshikov:

Но я скажу за автора — к сожалению, прямо сегодня можно найти сколько угодно восторженных статей типа «А вот есть такая замечательная фигня, как bash, щас я вам про нее расскажу...» — где unix way откровенно перехваливается неофитами. Это не помешает иногда компенсировать долей скепсиса.

Да, в этом-то и всё дело! Достало, что хвалят UNIX way. Что считают UNIX красивым и ещё и других учат. А использовать-то UNIX можно.

UPD от 2017-02-14: как минимум один комментатор сказал, что пересел с Windows на UNIX-подобные ОС и счастилив. Что поначалу он плевался от UNIX, но потом решил, что программировать под UNIX гораздо проще, чем под Windows. Так вот, я тоже сперва использовал и программировал на Windows. Потом пересел на UNIX. И сперва, конечно, было очень непривычно. Потом прочувствовал «философию UNIX», ощутил всю её мощь. Программировать под UNIX стало легко. Но позже пришло ещё одно озарение. Что UNIX неидеальна, а «философия UNIX» неабсолютна. Что программирование на «голом UNIX», с использованием C и Shell сильно уступает, скажем, Web-программированию. И далеко не только потому, что в Web-программировании используются языки, в которых трудно выстрелить себе в ногу, в отличие от C (тут языку C предъявить нечего, он намеренно является низкоуровневым). Но ещё и из-за всех этих quirks мейкфайлов, шела, языка C. Отсутствия удобных инструментов, систем сборки, менеджеров пакетов. Всё это, в принципе, можно было бы исправить. Вот я написал эту статью, чтобы открыть на это глаза тем, кто об этом не знает. У Windows тоже полно недостатков (я разве где-то говорил, что Windows лучше UNIX?). Но в чём-то Windows лучше UNIX (как минимум в некоторых особенностях Powershell). Сейчас я продолжаю использовать и программировать под UNIX. UNIX меня устраивает, мне достаточно удобно, хотя теперь уже я вижу многие его недостатки. Я не призываю бросать UNIX. Используйте UNIX дальше, просто не считайте его идеалом.

UPD от 2017-02-15: habrahabr.ru/post/321652/#comment_10070776.

UPD от 2017-02-15: habrahabr.ru/post/321652/#comment_10071096.

UPD от 2017-02-15: habrahabr.ru/post/321652/#comment_10071714.

UPD от 2017-02-16: понравился этот коммент: habrahabr.ru/post/321652/#comment_10066240.

UPD от 2017-02-16: многие комментаторы рассказывают, как же полезны и удобны UNIX системы. Что они есть уже десятки лет, на них работает весь интернет. Что они стабильны и прекрасно справляются с возложенными на них задачами. И даже удалённо переустановить GNU/Linux можно :) А я и не спорю. Я не призываю отказываться от UNIX. Я просто хочу, чтобы вы видели недостатки UNIX. UNIX работает, используйте его. Процитирую James Hague, на которого я уже ссылался:

Enough time has passed since the silly days of crazed Linux advocacy that I'm comfortable pointing out the three reasons Unix makes sense:

1. It works.
2. It's reliable.
3. It stays constant.

But don't--do not--ever, make the mistake of those benefits being a reason to use Unix as a basis for your technical or design aesthetic. Yes, there are some textbook cases where pipelining commands together is impressive, but that's a minor point. Yes, having a small tool for a specific job sometimes works, but it just as often doesn't.

Одно время я тоже, как и многие из вас, повёлся на эту «философию UNIX». Думал, что она прекрасна. А потом понял, что это не так. И вот этим своим открытием я хочу с вами поделиться. Мои мысли не новы. Они уже есть в приведённых мною ссылках. Я просто хочу сообщить эти мысли аудитории Хабра. Мой пост написан наскоро, ночью. Читайте скорее не его, а ссылки, которые я привожу. В первую очередь две презентации Пайка, в которых он «отменяет философию UNIX» и два поста от James Hague. Мой пост фактически написан, чтобы привлечь внимание к этим ссылкам.

Как минимум один из комментаторов сказал, что многие из названных мной «недостатков» UNIX недостатками не являются. Например, слишком короткие имена команд. Ну да. Это не недостаток. Но это пример необдуманного решения. Сиюминутного решения, принятого под влиянием обстоятельств, имевших важность тогда. Как и с тем примером с /usr или make. Я показываю, что UNIX была непродумана. Да и вообще, вглядитесь в историю UNIX! Сотрудникам Bell Labs не понравилась сложность проекта Multics. Они сказали: «Да ну этот Multics, давайте по-быстрому напишем свою ОС, запростецкую». И написали. Понимаете? ОС получилась довольно хорошей. Но не идеальной. UNIX — это хак. Успешный хак, который выполнил свою миссию и продолжает её выполнять.

В комментариях была мысль, что заголовок поста не соответствует содержанию, и что я критикую не самую суть, философию UNIX, а просто привожу некий список недостатков. Возможно даже не всего класса UNIX-подобных систем, а конкретных реализаций. Так вот, это не так. Да, статья начинается с перечисления мелких недостатков. Этим я обращаю внимание на то, что в UNIX полно костылей, как и в других системах. В том числе очень старых, оставшихся во всех UNIX системах и попавших во все стандарты. Но я критикую и саму философию UNIX. Основные принципы (но не все!). Язык C, UNIX shell, идею конвееров, «всё есть текст». Замечу, что компилятор C и make, хоть и являются по идее отдельными программами, всегда рассматриваются как неотъемлемая часть экосистемы UNIX. И входят в POSIX. Некоторые комментаторы пишут: «А я сижу в IDE и не использую этот ваш make». Ну окей, хорошо, мой пост предназначен скорее как раз для тех фанатиков, которые считают, что всякие IDE — это не труъ и что программировать нужно непременно используя голый C, make и shell.

И я не говорю, что философия UNIX (даже в тех местах, которые мне не нравятся) всегда не верна. Часто конвееры и shell-скрипты — это именно то, что нужно. Но не всегда.

Некоторые комментаторы указывают, что голый shell, make и прочее часто скрыты от глаз юзера всякими обёртками, всякими IDE, сложными системами сборки, GUI-интерфейсами и пр. Ну да. Так ведь это и есть признак кривости системы :) Когда что-то уродское покрывают слоем красоты. А ещё абстракции протекают. А потому использовать, скажем, autotools ещё сложнее, чем голый make. Потому что чтобы использовать autotools, нужно знать ещё и m4, make и shell. Да, да, всю эту цепочку языков, используемых при генерации окончательного мейкфайла.

Один комментатор приводит следующие принципы UNIX:

Write programs that do one thing and do it well.
Write programs to work together.
Write programs to handle text streams, because that is a universal interface.

С первыми двумя я согласен при условии, что они понимаются в отрыве от UNIX shell и конвееров. Их можно перенести даже на новомодные микросервисы, общающиеся с помощью REST. С третьим я не согласен (как я понимаю, подразумевается именно придумываение простого кастомного текстового формата для каждого случая вместо единого формата наподобие JSON). Часто текст — это именно то, что нужно. Но пихать его везде как universal interface глупо. На эту роль скорее претендует JSON или XML. Или, может, какой-нибудь формат для структуированных данных, который ещё не изобрели.

Многие указали на искусственность некоторых примеров на shell. Ну да, я знаю, что их можно было бы переписать на find -exec или xargs. Ну что вы хотите, наскоро написанная статья. Можно было привести примеры получше, просто мне не хотелось. Это не отменяет того, что в shell'е постоянно возникают проблемы со специальными символами. Которые нужно по-особому обходить. И вообще у shell'а полно quirks, которые нужно постоянно держать в голове. И он запускает новые программы на каждый чих.

Я вам ещё покушать принёс. Вот вам цитата от безусловно ещё одного вашего кумира Линуса Торвальдса:

iTWire: Systemd seems to depart to a large extent from the original idea of simplicity that was a hallmark of UNIX systems. Would you agree? And is this a good or a bad thing?

Linus Torvalds: So I think many of the «original ideals» of UNIX are these days more of a mindset issue than necessarily reflecting reality of the situation.

There's still value in understanding the traditional UNIX «do one thing and do it well» model where many workflows can be done as a pipeline of simple tools each adding their own value, but let's face it, it's not how complex systems really work, and it's not how major applications have been working or been designed for a long time. It's a useful simplification, and it's still true at *some* level, but I think it's also clear that it doesn't really describe most of reality.

It might describe some particular case, though, and I do think it's a useful teaching tool. People obviously still do those traditional pipelines of processes and file descriptors that UNIX is perhaps associated with, but there's a *lot* of cases where you have big complex unified systems.

And systemd is in no way the piece that breaks with old UNIX legacy. Graphical applications seldom worked that way (there are certainly _echoes_ of it in things like «LyX», but I think it's the exception rather than the rule), and then there's obviously the traditional counter-example of GNU emacs, where it really was not about the «simple UNIX model», but a whole new big infrastructure thing. Like systemd.

Now, I'm still old-fashioned enough that I like my log-files in text, not binary, so I think sometimes systemd hasn't necessarily had the best of taste, but hey, details…


UPD от 2017-02-18: ещё по поводу надуманных примеров на shell. Вы говорите, примеры надуманные, что можно сделать find -exec или xargs. Да, можно. Но как минимум сам факт того, что нужно постоянно держать в голове, что, мол, цикл нельзя и нужен -exec и xargs — это уже костыль. Проистекающий из принципа «всё есть текст», ну или из слишком тупой реализации этого принципа в UNIX shell.

Итак, сейчас я приведу такую задачу, в которой любое решение будет уродским, даже с использованием find -exec и xargs.

Вернёмся к моему примеру с touch'ем. «Как touch'нуть все файлы в папке foo (и во вложенных)?» Допустим, что нужно не touch'нуть их, а grep'нуть из них все строки со словом bar и положить результат туда же. Т. е. для каждого файла file сделать grep bar file > tmp; mv tmp file. Как быть? Если делать решение с циклом, то мы упираемся в те пять хаков, которые нужно сделать, чтобы не выстрелить себе в ногу. Результат будет таким, со всеми пятью хаками:

find foo -print0 | while IFS="" read -rd "" A; do
	grep -- bar "$A" > tmp
	mv -- tmp "$A"
done

Ладно, хорошо, мы знаем, что имя файла начинается на foo, а потому не может начинаться с дефиса и пробела. Но оно может заканчиваться на пробел, а потому тот трюк с IFS всё равно нужен. Так что единственный хак, от которого можно избавиться, зная, что имя начинается с foo — это написание --. Но даже от этого хака я бы не советовал избавляться, т. к. постоянное использование -- даёт понять читающему: «Да, я подумал об этом». Это как условия Йоды.

Окей, можно ли этот пример написать проще с использованием xargs или find -exec? Если бы каждый файл нужно было всего лишь touch'нуть, то да, можно было бы написать существенно проще. Но если нужно выполнить два действия: grep и переименование, то существенного упрощения мы уже не получим. Два действия означают, что нам уже нужно запихивать эти два действия в вызов shell'а, в sh -c. Как будет выглядеть результат? Может быть, так?

find foo -exec sh -c "grep -- bar '{}' > tmp; mv -- tmp '{}'" ';'

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

find foo -exec sh -c 'grep -- bar "$1" > tmp; mv -- tmp "$1"' dummy '{}' ';'

Видите? Опять хак. Нам пришлось передать имя файла через $1. И по-прежнему нужно помнить, что нам нужны двойные кавычки вокруг $1. То же самое было бы с xargs. Опять нужен sh -c и опять нужно передавать аргументы через $1.

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

Теперь по поводу другого примера. Где нужно удалить все файлы определённого размера. Да, всё это можно сделать одним вызовом find. Там есть опции и для проверки размера, и для удаления. Да. Вот только я вижу здесь хак. Хак в том, что find имеет фактически в себе целый sublanguage, подъязык. Язык вот этих вот опций. Почитайте хорошенько ман find'а. Вы узнаете, что, оказывается, порядок опций find'а имеет значение. Что каждая опция имеет truth value, т. е. булевское значение. Что можно по-хитрому комбинировать эти опции. Что в зависимости от порядка опции, от их truth value find принимает решение, в какой момент нужно остановить обработку опций для данного файла и нужно ли descend в данный каталог (т. е. нужно ли искать внутри этого этого каталога).

Я помню, как однажды жутко оплошался, не зная этих тонкостей. Я набрал find -delete -name '*~' вместо find -name '*~' -delete или что-то такое. Ну подумаешь, думал я, опции не в том порядке. Смысл же тот же. И find удалил всё. Снёс мои важные файлы. Потом я восстановил из бекапа, так что всё ок. Это потом уже я понял, что -name имеет truth value true в случае, если файл соответствует маске. И если -name вернул true, то обработка опций продолжается.

Что тут плохого? Плохо то, что find имеет свой sublanguage. Что это ещё один язык в дополнение к shell. (А sed, кстати говоря — это ещё один язык, а awk — это ещё один язык и так далее, авторы UNIX'а любили создавать по языку на каждый чих.) Нужно было вместо этого сделать так, чтобы find только умел искать файлы. А всю остальную функциональность нужно вынести из него. Проверки на размер файла должны быть снаружи. А если find'у нужно принять решение, нужно ли descend в данный каталог, то он должен вызывать внешний callback. Да, в UNIX shell так вряд ли получится. На то он и UNIX shell.
Аскар Сафин @safinaskar
карма
45,0
рейтинг 0,0
Самое читаемое Разработка

Комментарии (698)

  • +161
    «Статья написана наскоро, «полировать» дальше не хочу, скажите спасибо, что написал.»
    Охренеть, одолжение сделал :)
    • –21
      Дюже странно, что карму еще не слили. Ну, хабр- он такой…
      • 0
        Уже слили, не волнуйтесь
        • –2
          Ну, мне-то и сливать было нечего, но мир не без добрых людей- спасибо за минусы
          • –2
            кто-то оголтело лепит минус просто потому что сказанное идет вразрез с его убеждениями, а кто-то ставит плюс к статье за то что в ней есть котик. Скоро котировки валют на месяц вперед будет проще предсказать чем собственную карму/рейтинг на хабре.
    • +74
      это ж сарказм, замешанный на философии UNIX
    • +8
      Зашел в профиль посмотреть другие посты автора. Опа!

      • 0
        И?
  • –16
    Да, всё так. Я бы ещё проехался по любимому языку юниксоидов — голым сям, Уже лет 20 нет ни одной причины не использовать вместо него си с плюсами, даже для системных вещей, тем более что в с-стиле можно и на плюсах прекрасно писать.
    А вообще проблема не в юникс, не в прочих ос или инструментах, проблема в людях. Из любой достаточно долгоживущей и сложной системы, над которой работает масса людей, по факту получается свой клубок костылей с велосипедами, можно даже никакие статьи с критикой не читать. Панацеи тут быть не может, поэтому просто надо набираться опыта и самому делать хорошо. Получится не сразу, а когда начнет получаться, будет уже поздно. Выхода нет, смиритесь.
    • –4
      На работе всегда говорю, «ошибки не в людях, а в сервисах». Люди не ошибаются, они делают не всегда то что от них кому-то хочется. А вот сервисы уже предназначены для того, чтобы делать то, что хочется его владельцу, поэтому если делают не то — ошибаются.
    • +3
      Проблема в том что для системного программирования кроме С и С++ пока к сожалению ничего нет (ну вот появился Rust но он еще мало распространен… да и с синтаксисом некоторые вопросы к интуитивности, в тех же же C# или Java все гораздо более понятно, причем сходу, без необходимости погружаться в нюансы языка).
      • –6
        Ну так большая разница же, с и с++, я про что и пытался сказать. С++ рулит, в отличие от.
        • +13

          C++ — это такой ужасный монстр. И иногда вместо C++ нужно использовать C. Чтобы вместо вот этого монстра использовать монстрика поменьше

          • 0
            Настоящая причина использовать Си вместо С++ в 90% случаев куда тривиальнее: отсутствие компилятора С++ для конкретного устройства. Никто же не заставляет использовать все эти «монструозные» вещи типа буста, можно даже писать большую часть кода на общем подмножестве.
          • +5
            Монстры только у людей в головах. Ничего же не мешает вам писать на ++ в стиле си и аккуратно использовать некоторые полезные плюшки, тот же RAII, но без фанатизма, без буста, без лямбд.
            А вот в голом си приходится изголяться, дефайны, goto, MyObject_DoSomething(MyObject* self) и прочие радости.
            • 0

              Я считаю, у C++ нет самодостаточных подмножеств, не считая самого C++, разумеется (C, к сожалению, не является подмножеством C++). Попытка выделить некоторое подмножество C++ для своего проекта обречена на провал. Вот допустим, есть проект "в стиле C" для UNIX, я хочу заюзать в нём RAII для файловых дескрипторов (fd). Окей, написал свой объект-обёртку для fd. Потом выясняется, что нужно либо запретить копирование для этого объекта, либо реализовать в конструкторе копирования dup. И не зависимо от выбранного варианта нам нужно уметь возвращать наш объект из функции, а для этого уже нужен конструктор перемещения, а это уже C++11. Ну и так далее, так постепенно вы притянете весь C++ во всей своей красе.


              When you’re programming C++ no one can ever agree on which ten percent of the language is safe to use. There’s going to be one guy who decides, “I have to use templates.” And then you discover that there are no two compilers that implement templates the same way

              https://gigamonkeys.wordpress.com/2009/10/16/coders-c-plus-plus

              • +3
                Потом выясняется, что нужно либо запретить копирование для этого объекта, либо реализовать в конструкторе копирования dup. И не зависимо от выбранного варианта нам нужно уметь возвращать наш объект из функции, а для этого уже нужен конструктор перемещения, а это уже C++11

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

                https://gigamonkeys.wordpress.com/2009/10/16/coders-c-plus-plus

                напомнило
        • +3
          Я раза 3-4 порывался перейти с C на C++, даже в некоторых больших проектах на плюсах принимал участие, но не прёт меня от них, всегда возвращался к голому C. Единственное, чего мне не хватает на «голом» по сравнению с плюсами — это libslave (скоро допишу свою на сях), нормальной библиотеки под протобуф и RapidJSON (тоже можно пережить).

          Голый C прекрасен, просто он не всем подходит.
          • +3

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

            • +4
              BF вообще замечательный, его лаконичность потрясает. А если вам не нравится, то вы просто школотроны, единственно на что способные — кнопки по формам расставлять. Fixed for ya.
            • –1
              Именно! Все языки по-своему прекрасны и у каждого найдутся приверженцы.
    • +13
      Уже лет 20 нет ни одной причины не использовать вместо него си с плюсами, даже для системных вещей, тем более что в с-стиле можно и на плюсах прекрасно писать.

      Есть. libstdc++ во флешу не пролазит. Толстая слишком.

      • –23
        А вот эта вся экономия на копеечных флэшах она как правило боком выходит рано или поздно. Должен быть запас минимум в 2 раза, если планируется хоть какое-то минимальное развитие продукта. У нас тоже в свое время в одном из продуктов лет 12 назад наэкономили, поставили 4ГБ, и рамки впритык. Потом через 2-3 года сразу в 8 раз запас сделали, экономия сильно убыточная вышла по факту.
        • +41
          4ГБ

          У нас 32КБ

          • +4

            На attiny младших ещё меньше, и ничего, на плюсах писать вполне можно. Без экзепшонов и rtti, конечно, но плюсы ими не ограничиваются.

            • 0

              Ну я их в итоге завёл там без стандартной библиотеки путём выключения лишнего во флагах компиляции и написанием заглушек под хлам типа __verbose_terminate_handler. Что не отменяет упитанности libstdc++.

        • +2
          А вы вкурсе, что есть ОС (стоит отметить, *nix ОС) под всякие встраиваемые системы и МК? Там такая память только в очень сладких снах может сниться.
          • –3
            Я где-то говорил что предлагаю всем 4 гига ставить? Это пример был, из личного опыта. Если у Вас 32 КБ (это наверное что-то космическое суперотказоустойчивое), то можно взять запас до 64 КБ, да в конце концов, из любого правила есть и исключения, пишите в этом случае на си, на здоровье, не надо же все советы так буквально воспринимать, а то я смотрю народ прям переволновался. Под 32 кб можно и на асме написать.
            • 0
              можно взять запас до 64 КБ

              У меня не получалось упихнуть libstdc++ и в 64 кб. Говорю же, толстая слишком. А без неё запас неплохой есть, да.

      • +1
        Так не нужно использовать std от C++. Это чудовищное поделие. Там из полезного только exceptions, но я думаю их как-нить можно вынуть оттуда, не таща с собой весь остальной хлам.
        А сам С++ с RAII и остальным весьма крут, хотя сильно больше нюансов, чем в голом С.
        • –3
          <сарказм>
          Не оскорбляйте святое. Люди привыкли писать на голом С, это развивает внимательность, аккуратность. Сделал, как говорится, fopen, не забудь про fclose, да и код получается длинный, солидный. А все эти ваши гейские RAII — не нужны и не влазят в 8 кБ памяти, особенно если boost весь ещё заинклюдить.
          </сарказм>
        • –1
          Механизм исключений без RAII бесполезен. Плюс, очень удивительно, что вы выделяете самую запрещаемую в проектах фичу языка как его основное преимущество
          • +1
            Ну так я и говорю, что нужно RAII + exceptions. Но их реализация находится в райтайме С++. Хз кем и где она запрещена. Везде, где писал на С++ все использовали исключения и RAII как самое базовое, что С++ предоставляет по сравнению с голым С.
            То, что это в публичном стайлайде гугла написано, так это сильно не так внутри и сильно зависит от команд и наличия легаси кода. А изначально это пошло из-за плохой реализации исключений в старых компилярах с точки зрения производительности.
            • +2
              То, что это в публичном стайлайде гугла написано, так это сильно не так внутри и сильно зависит от команд и наличия легаси кода

              Вот что написано в публичном стайлгайде гугла.


              On their face, the benefits of using exceptions outweigh the costs, especially in new projects.
            • +1
              А изначально это пошло из-за плохой реализации исключений в старых компилярах с точки зрения производительности.

              никогда не понимал и не пойму, какая разница, насколько шустро отрабатывается исключительная ситуация
              • 0

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

                • 0
                  Какие, нафиг, слухи? SJLJ — это единственное что работает на всяких хитрых, нестандартных, платформах (типа тех же микроконтроллеров), а dwarf2 — очень и очень жирный (что может быть, опять-таки, большой проблемой для микроконтроллеров).

                  Вот тут подробнее.
              • 0
                Верно, но старая реализация исключений просаживала производительность просто от куска try-catch. То есть даже той ветви, которая успешная.
                На хабре где-то было про реализацию исключений статья.
                • 0
                  В нынешний век интерпретаторов и П-кода это не то чтобы просадка, это погрешность измерений =)

                  Там расходы были — пяток лишних ассемблерных инструкций.
              • 0
                Нет, ну overhead есть даже если нет исключений. Скажем, в Windows надо для каждого try, в том числе скрытого, создать элемент SEH, а в конце — удалить его. Да, это мизер.
      • 0
        -static-libstdc++ не отрабатывает?
      • +1
        libstdc++ во флешу не пролазит. Толстая слишком.
        Давно, если честно, не смотрел, но были же проекты uclibc++ и подобные, все умерли?
  • +43
    И эти файлы надо заново читать и заново парсить при каждом вызове ls -l! Было бы гораздо лучше использовать бинарный формат. Или БД. Или некий аналог реестра. Как минимум для вот таких вот критичных для производительности ОС файлов.

    Не стоит недооценивать производительность текстовых файлов.
    Собственно, какая вам разница, будет ли конец строки обозначать символ \0 или символ \n?
    SQLite/Berkley или на таких размерах проиграют по производительности.

    Полагаю, что чтение и парсинг /etc/passwords выиграет по скорости у чтения из реестра на порядки. Но это все в целом не важно, потому что роль идет даже не о миллисекундах — я набросал простенький скрипт на perl, он с парсит /etc/passwd с помощью регулярного выражения 100 тысяч раз за ~3s.

    printf внезапно является далеко не самым быстрым способ вывода информации на экран или в файл

    Форматируемый вывод оказывается не самый быстрый вывод! Я прямо-таки потрясен этим откровением. А нет, не потрясен. Это все написано в любой книге по С.
    • +2
      Собственно, какая вам разница, будет ли конец строки обозначать символ \0 или символ \n?

      Скорее, в случае с БД, она ничем заканчиваться не будет, будет указан её размер.
      /etc/passwords маленький файл для примера. А вот с большим файлом, со сложным форматом (вложенные секции, например), выигрыш будет на стороне БД. Файл не надо будет разбирать на строки, и эти строки парсить в дерево.
      • 0
        Скорее, в случае с БД, она ничем заканчиваться не будет, будет указан её размер.

        В postgresql, например, безразмерные строки будут незначительно быстрее строк с фиксированным размером.

        • +1

          Вы путаете "fixed size strings" и "pascal strings".
          "Безразмерные" строки в postrgesql как раз паскалевские и хранят свой размер (каламбур).

    • +2
      Предполагается что у баз данных есть индексы и самое главное контроль целостности до записи(имеется в виду завершение транзакции), чего нет у идеологии 'все есть текст', т.е. в случае с /etc/passd об ошибке скорее всего узнаем по факту использования.
    • +4
      Форматируемый вывод оказывается не самый быстрый вывод!

      Дело не в этом, а в том, что строка формата разбирается каждый раз во время выполнения.


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

    • –1
      Форматируемый вывод оказывается не самый быстрый вывод! Я прямо-таки потрясен этим откровением. А нет, не потрясен. Это все написано в любой книге по С.

      Окей, может быть вы это уже знали. А я это в своё время не знал. Я и подумать не мог, что, оказывается, вот этот вот дефолтный момент в C неэффективен. Я думал, что не могли же умные дядьки ошибиться и какую-то ерунду мне подсунуть. Естественно, в какой-то момент я начал догадываться, что форматный вывод неэффективен. Но опять-таки, я подумал, что раз C делали умные дядьки, то, видимо, он не до такой степени медленный. Но нет, как я выяснил от автора H20, форматный вывод таки существенно медленнее неформатного. Ну вот я сейчас этим откровением с Хабром делюсь.


      Вдобавок, во многих реализациях стандартной библиотеки C++ (как минимум до недавнего времени) потоки ввода-вывода были реализованы поверх форматных функций C! (Facepalm!) То есть в API C++ строк формата уже нет, внутри всё можно реализовать без них. Но эти идиоты всё равно внутри пихают форматные строки. Чтоб медленнее было. Я-то думал, что программисты умные. Что реализуют всё всегда как надо. Как бы не так! Есть ли этот баг по-прежнему в основных реализациях стандартной библиотеки C++, я не знаю. Вполне мог остаться

      • 0

        Там, где мне, наверное, единожды за последние года три это было важно, istream был быстрее scanf.


        Ну а самым быстрым вариантом был mmap + парсер на boost::spirit + boost::string_view. Но это так, заодно к слову о монстрах C++ vs C.

    • +18
      Особенно умиляет твердокаменная уверенность в том, что при крахе системы у бинарной конфигурации больше шансов выжить, чем у текстовой.
      Оставляя за скобками такой важный нюанс, что текстовую конфигурацию, при повреждении, куда легче и быстрее восстановить вручную, чем бинарную без дополнительного специфического инструментария
      • –7
        Бинарные сами следят за своей целостностью. Убить реестр внезапным ребутом почти не реально.
        • +5
          юзеры ещё не то могут убить… Приходилось чинить. Там не все в двух копиях, вообще-то.
        • 0
          Согласен — начиная с 7ки, угрохать регистр падением системы стало практически невозможно. До этого — сколько угодно.
          Тем не менее — если регистр повреждён (да даже действиями пользователя) до степени незагужаемости системы, это требует специфических инструментов для ремонта, в отличии от текстовых конфигов.
          С точки зрения производительности системы, можно хранить в памяти результат чтения текстовых конфигов и обращаться к нему (рано или поздно вся эта концепция systemd к такому и приведёт).
          • 0
            Согласен — начиная с 7ки, угрохать регистр падением системы стало практически невозможно.

            Отключение питания на этапе загрузки убивает реестр и на 7. Никогда не понимал логики, зачем надо писать в реестр до логина пользователя.
            • 0
              На каком? Как минимум до этапа chkdsk ОС точно ничего на диск не пишет.
              • 0
                На каком?

                Где-то в районе анимированного бут-лого или сразу за ним.
                • 0

                  У меня есть многострадальный комп, которым мне лень заниматься. Для кино и всякого. У него что-то с железом, что он часто ресетится. Иногда не включается. Но проводом подергал и завелось. Пару раз вис и не загружалась винда из за одного диска. Я его и сам не жалею. Долго выключается — ресет, долго думает — ресет, долго не включается — ресет. Винде по барабану. Живет не тужится.

                  • 0
                    Долго выключается — ресет, долго думает — ресет, долго не включается — ресет

                    В вашем опыте ключевое слово «долго», т.е. весь io уже закончился.
                    В моём опыте, всё внезапно и с железом всё нормально — старт системы, потеря питания, «убитый» реестр.

                    Показательно, что это не единичные случаи, несколько раз восстанавливал юзерские, когда в нервах ресет жмут на загрузке. И у себя словил 2 раза, чистой воды невезение, один раз аккум ноута в 0 ушёл на загрузке, второй раз электросети «уронили» десктоп.
                • 0
                  Это ооооооочень пространное указание точки времени. Там мягко говоря много всего в этот момент происходит.
                  • 0
                    Суть то одна, пропадание питания в этот момент и как результат битый software.
                    • 0
                      В чём проблема воспользоваться резервной копией? По-умолчанию в винде включены опции по созданию точек восстановления и копий реестра…
                      • 0
                        Которые умельцы сроду отключают и жалуются, что глючную винду приходится переустанавливать после каждого чиха.
            • 0
              Ну как зачем — процесс сверки обнаруженных устройств с существующими с last known good, например, или ещё какое-нибудь вуду. Регистр — он не для пользователя, по большому счёту, точнее у пользователя есть свой кусочек, в профиле, куда и начнут писАть, после того как он залогинится.
              Я уже было решился спросить у человека какие именно технические детали позволяют ему с таким апломбом утверждать о самовосстановлении регистра (а вдруг?), а тут вы пришли и… разрушили мою веру в светлое бинарное завтра юникс-систем.
              • 0
                Ну как зачем — процесс сверки обнаруженных устройств с существующими с last known good

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

                Зачем восстанавливать то, то не упало? Механизмы записи в реестр сделаны для поддерживания его консистентного состояния при обрыве записи, а транзакционные механизмы NTFS не дают сработать и им.
            • 0
              BCD хранит свои конфиги в кусте реестра. Хотя правда не в курсе, он только читает или ещё и пишет?
          • –3
            До этого — сколько угодно.

            Не соглашусь. На своей XP я никогда не видел разрушение реестра. Хотя и вырубал и во время загрузки, и во время выключения.
            • +2
              На вкус и на цвет все фломастеры разные — может у вас контроллер диска какой дружелюбный. То, что молния никогда в вас не попадала, вовсе не значит, что она не попадала в других людей.
              • 0
                Я использовал весьма разное оборудование. Видимо, я везунчик.
                • 0

                  Возможно дело в том, что раньше можно было ставить систему на FAT32 раздел со всеми вытекающими ;-)

                  • 0
                    на NTFS оно точно также в капусту билось, но как правило очень невоспроизводимо. какой-нить race condition при записи в глубине дискового стека, совпадающий с зависанием/вырубанием системы.
            • +1
              Аналогично. Сколько ни отрубай «жестко». Ни на XP, ни на 2к.
    • 0
      А зачем там регулярка, там же фиксированный набор полей? Тот же GAWK в таких случаях (простые текстовые файлы с фиксированным набором полей) вообще рвет всех. Причем даже на гигабайтных простынях данных.
  • +30
    Про существование зомби-процессов все говорят: «It's for design».

    Зомби-процесс — это завершенный дочерний процесс, который не «похоронен» родителем — по сути, от процесса остается минимальная запись в таблице процессов, содержимое буферов обмена и код завершения.

    Обычном kill'ом зомби не убиваются

    Убиваются, конечно же, только целиться надо в родителя. Пример: kill $(ps -A -ostat,ppid | awk '/[zZ]/{print $2}')

    Долгие и пространные рассуждения про shell забавны в своей надуманности, но хотелось бы отметить, что сравнивать его возможности надо не с возможностями php, а с возможностями cmd.
    • +3
      А если родитель еще нужен?
      • +1
        Если есть зомби, то с родителем не всё в порядке, т.е. он уже не нужен.
        • +8
          А если там критичные данные? Например ваша зарплата за год.
          • –7
            Вы сейчас о чём говорите, какие критичные данные, какая зп?

            Если есть зомби, то скорее всего родителя уже нет. Просто нет. Нет, от слова совсем. Со всеми данными.
            • +4
              Все понятно. В следующий раз рекомендую высказываться на тему в которой хоть немного разбираетесь.
            • +8
              Если есть зомби, то скорее всего родителя уже нет. Просто нет. Нет, от слова совсем. Со всеми данными.

              Зомби-процесс — это дочерний процесс, родитель которого не удосужился получить код завершения через wait. Если родитель умирает, то зомби наследуется init, который его без сожалений убивает.


              То есть, наличие зомби говорит о том, что родитель как раз есть. Другое дело, что в нём баг, но процесс есть.


              Не понимаю, за что заминусовали tgz.

              • +1
                Не в качестве несогласия с вашим комментарием, а как небольшая поправка. Когда родитель умирает дочерний процесс определенно наследуется каким-то другим процессом, но это совсем не обязательно именно init.
                • 0

                  Да, согласен. Просто осиротевшего зомби в *NIX усыновляет процесс с PID=1, а его по инерции часто init называют. Хотя, конечно, всё может быть и по-другому.

                  • +7
                    Опять же не совсем верно. Кто наследует дочерний процесс после смерти родителя «implementation defined», т. е. это не обязательно init или процесс с pid=1. Более того в linux вообще может быть несколько процессов, которые собирают осиротевших детей (смотрите man prctl ту часть где описывается PR_SET_CHILD_SUBREAPER).
                    • +2

                      Ага, спасибо! Просто у Стивенса и Раго именно про PID=1 написано. Ну, теперь буду знать. :)

                • 0
                  Sic!
                  • 0

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

                    • –1
                      Или что вы хотели сказать?


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

                      Зомби жив, пока родитель через wait состояние не получит. Единственное разумное, почему родитель этого не делает (я не беру в расчет отсутствие в коде этой возможности) — родителя уже нет или он не в состоянии нормально работать.
                      • +4

                        Вы недооцениваете вероятность наличия багов. :)

                      • 0
                        А если у родителя просто нужный тред заблокировался на IO, а все остальное хорошо и в порядке?
              • –1
                Просто хипстеры не умеют так:
                29755 pts/0 Ss 0:01 \_ /bin/zsh
                6123 pts/0 S+ 0:00 | \_ ./zombie
                6124 pts/0 Z+ 0:00 | \_ [zombie]

                [some magic]

                29755 pts/0 Ss 0:01 \_ /bin/zsh
                6123 pts/0 S+ 0:00 | \_ ./zombie


                И зомби умер. Без убивания папы.
                • +22
                  Я один вижу в этом ASCII-арте длинные грейдеры, убирающие снег?
          • +1
            А если RAM сдохнет? Или контроллер? Или питание вырубится?

            Если ваша зарплата за год имеется только в оперативной памяти одного сервера, валить надо из такой конторы.
            • +1
              Следуя этой логике можно сделать rm -rf /, а объяснить все тем, что мог ведь и контроллер сдохнуть. В маразм не впадайте. Ваша зарплата зависит от ваших действий, а не от того что лежит в памяти конкретного сервера.
              • 0
                Нет, следуя этой логике, нельзя сделать rm, потому что логика в том, чтобы не хранить критически важные данные только в оперативной памяти одного процесса на одном сервере.
                • 0
                  Маразм все же побеждает. Перечитайте изначальный пост, вопрос был не про зарплату. По существу есть что сказать?
            • +1
              да что вы обычная черная бухгалтерия… все на RAM диске и бекап в крипте в облако в Зимбабве…
      • +4
        Если родитель нужен, то вполне может быть, что этому родителю нужна информация о том, как скончался его ребенок (код возврата, короче), так что какую-то информацию о завершившемся процессе все равно придется сохранть. Zombie процесс — просто способ сохранить эту информацию до тех пор, пока ее не запросит родитель.

        Но если вам это не нужно, то вы можете просто поправить обработчик SIGCHLD и вот вам автоматическая сборка этих Zombie. Это всего одна строка кода, так что не супер тяжелая задача.
        • –2
          Как вставить 1 строчку кода в уже запущенный бинарник?
          • +3
            Если процесс не собирает своих детей, то значит они ему нужны и значит Zombie процессы должны быть, либо это просто недосмотр со стороны программиста(ов), который написали программу. Странно винить Unix за недосмотр программистов.
            • –2
              Где я винил unix?
              • +1
                Ок нигде. Тогда что к обсуждению должен был добавить ваш вопрос про то, как вставить 1 строчку кода в уже запущенный бинарник?
                • 0
                  Наверно понимание того что вставить строчку нельзя по условию задачи.
                  • 0
                    Какой задачи? Избавиться от zombie? Так вроде как я вам выше объяснил, что zombie либо может быть нужен родителю и от него не нужно избавляться, либо родитель содержит ошибку — и это уже совсем другая история, исправлять ошибку в программе позволяя небезопасное действие странно.
                    • 0
                      А если зомби не нужен?
                      Вот прямо сейчас на ноуте:
                      20157 ? Ssl 0:09 gvim
                      20163 ? Z 0:00 \_ [python3]
                      Зомби мне не нужен, а vim содержит несохраненные данные.
                      • +4
                        Операционная система не знает ничего о логике приложения, она просто не может узнать, что zombie больше не нужен. Zombie будет удален тогда, когда гарантированно известно, что он не нужен и не раньше.

                        Если программа порождает дочерние процессы и не собирает их, хотя они ей не нужны — это бага в программе. Ее нужно фиксить в программе.
                        • 0
                          Ну так кроме ОС у нас еще есть админ. А у админа есть некоторые инструменты.
                          • +2
                            То что админ есть, не значит, что ОС должна разрешать потенциально небезопасные действия (а убийство дочернего процесса, без разрешения родительского процесса — потенциально опасное действие, потому что логика родительского процесса может быть к этому не готова). Давайте все программы будут лазить друг к другу в память — админ же есть, он всех хулиганов накажет.
                            • 0
                              kill -9 потенциально небезопасен, но ОС же позволяет это делать, не так ли?
                              • 0
                                Так, а еще kill позволяет избавиться от zombie убив родителя, не так ли? И если родитель не собирает своих детей, хотя должен — то убивать нужно именно его, а не уже мертвый процесс, который ни в чем не виноват. Но как и всегда с kill -9 вы делаете это на свой страх и риск и не жалутесь на то, что в приложении могут быть несохраненные данные. Так что строго говоря, у администратора, который сам себе придумывает несуществующую проблему zombie процессов, все таки есть средство, чтобы с ними побороться.
                                • 0
                                  Средство есть, только это совсем не kill -9 для папы.
                                  • 0

                                    То есть вы утверждает, что где-то в стандарте posix описывается способ удаления zombie, который не сводится к вызову wait со стороны процесса родителя и гарантированно работает? Поделитесь выдержкой из Posix или SUS.

                                    • –2
                                      А с чего это должно быть написано в стандарте? У вас есть стандарт как ложку ко рту подносить? Нет? А кушаете как?
                                      kill -9 ppid в посиксе описан?
                                      • +1
                                        У вас такая бурная реакция на все стандарты или только на те, что вам не нравятся? Касательно вашего вопроса, нет у меня нет стандарта как подносить ложку ко рту, но ложку ко рту я подношу себе сам, а не прошу это делать за меня какого-нибудь дядю. С другой стороны еда, которую я покупаю в магазине чтобы есть, стандартам соответствовать должна — потому как я не делаю ее сам.

                                        Но возвращаясь к делу, стандарт — это форма описания гарантий. После всей той драмы, которую вы тут развели про зарплату, было бы странно если бы ваше решение не предоставляло разумных гарантий надежности. И под гарантииями надежности я имею ввиду что-то сильнее чем «я попробовал и у меня работает». А теперь вы можете сказать что-нибудь по существу?
                                        • –2
                                          У меня? Бурная реакция? Мы точно один сайт сейчас читаем? Драму какую-то нашли.
                                          И в словарик загляните на букву С, что бы понимать что такое стандарт.
                                          • +2
                                            То есть не можете. Спасибо за время потраченое зря время.
                                            • –2
                                              Не хочу.
      • 0
        Если родитель нужен, пробуем ему послать SIGCHILD, но скорее всего это не поможет. Тогда цепляемся к родителю через gdb, и от родителя уже запускаем waitpid() на pid зомби-процесса:
        # gdb
        (gdb) attach 19595
        (gdb) call waitpid(19698,0,0)
        $1 = 19698
        (gdb) detach
        
    • +3
      А зачем сравнивать шелл с возможностями cmd? Не, ну серьезно? Зачем выбирать какое-то другое древнее дерьмо мамонта и сравнивать с ним?

      Если мне что-то нужно автоматизировать в windows — я возьму вовсе не cmd.
      • +9

        Ну так и на линуксе народ автоматизацию на питоне сейчас каком-нибудь пишет.

        • +1
          Я вам больше скажу — у JavaEE контейнера Weblogic внутри тоже jython. И это удобно.

          Разница в том, что для управления чем-то при помощи скриптов изнутри есть API, а не предлагается вызывать команды, которые вернут неструктурированный поток байтов типа stdin.

          Ну т.е. нормальная современная полноценная автоматизация — это вовсе не шелл, в его оригинальном виде. Ну и не cmd конечно же.
      • +8

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

  • +7
    Очень похоже на выдержки из Unix Haters Handbook. Прочитать эту книгу для общего развития нужно, но в работе использовать не стоит :)
  • +13

    К сожалению, их более новые и продуманные системы, где решены многие из упомянутых проблем — OS Plan9, OS Inferno — не взлетели. Не нужны народу элегантные системы, в которых нет этих костылей — наверное, скучно без них. Я много лет работал с OS Inferno, и это буквально "открыло глаза" на многие проблемы *NIX. Пока радует только рост популярности Go, может хоть одна из их попыток хоть немного исправить сверх-популярные UNIX и C спустя 40 лет окажется относительно успешной.

    • +2
      Возможно redox взлетит…
      • +9
        К сожалению, какой бы хорошей не была система, она скорее всего не взлетит. Нужно пробить огромную инертную массу в виде существующих и как-то работающих технологий, решений, знаний и специалистов. Это зачастую гораздо сложнее чем придумать что-то новое и гениальное.
        • +2
          Вода камень точит…
        • +5
          Нужно пробить огромную инертную массу в виде существующих и как-то работающих технологий, решений, знаний и специалистов.

          ЕМНИП, создатели Plan9 именно так и говорили. Поэтому и не взлетело.
    • +1
      Не нужны народу элегантные системы

      Думаю, проблема немного не в этом. Проблема кроется в бизнесе, где хотят минимальной жертвой получить как можно больше.
  • +24
    Итак, я не хочу сказать, что UNIX — плохая система. Просто обращаю ваше внимание на то, что у неё есть полно недостатков, как и у других систем. И «философию UNIX» я не отменяю, просто обращаю внимание, что она не абсолют.


    Вы критикуете недостатки полувековой давности, которые в повседневной работе уже давно обернуты современными инструментами.

    И да, есть такое дело, «отвергаешь — предлагай». Более удобный GUI, сравнимый по производительности с Shell, новые GUI-утилиты, способные склеиваться выводом-вводом (да хоть TermKit) — и без copy-paste, так как я не хочу повторять свои «макросы» Mega-GUI-Shell руками, да еще и параметры хочу.

    Что касается C… вас кто-то уговаривает на нём писать? Make кстати вчистую уже тоже давно никто не использует. Можно продолжать, но зачем, «скажите спасибо что» прокомментировал.
    • +7
      >Вы критикуете недостатки полувековой давности, которые в повседневной работе уже давно обернуты современными инструментами.

      Вы правы. Но я скажу за автора — к сожалению, прямо сегодня можно найти сколько угодно восторженных статей типа «А вот есть такая замечательная фигня, как bash, щас я вам про нее расскажу...» — где unix way откровенно перехваливается неофитами. Это не помешает иногда компенсировать долей скепсиса.

      Хотя наверное не в таком стиле, все таки — а именно предлагая что-то взамен.
    • +5
      > Вы критикуете недостатки полувековой давности, которые в повседневной работе уже давно обернуты современными инструментами.

      Seriously? Многие аспекты системы до сих пор представляют собой кучи шелл-скриптов различной степени упоротости. Sysvinit, всякие утилиты для упаковки-распаковки пакетов и т.д. Я даже утилиты для работы с ФС на шелле видел. Паковали когда-нибудь свои приложения? debscripts? rpmbuild? Ага, можно взять fpm и не париться! Но как же post/pre install/uninstall хуки? Я уж не говорю, что сами по себе обертки это часто тоже скрипты. Сейчас правда модно стало говнокодить на питоне, а не на шелле.
      • +4
        Sysvinit
        Его таки начали закапывать, хотя, не всем это нравится (но не будем разводить ту холивар на тему Sysvinit vs systemd).
        • +1
          Да уже закопали во всех самых популярных дистрах
    • +8

      Вот именно что обернуты а не выкинуты. В этом и суть костылей. ..

    • 0
      Ну статья написана в ответ на статью «в винде в дате драйверов есть кривое легаси, которое ни на что не влияет но оно кривое». Вполне адекватный ответ, в UNIX-подобных тоже есть кривое легаси.
  • +15
    man hier

    /usr/local — хранит локально собранное ПО, которое не управляется пакетным менеджером и не входит в первоначальный состав системы.

    /opt — обычно для самодостаточного ПО, которое упаковано не по файловому стандарту *nix. Я например туда Oracle JDK всегда распаковываю.

  • +18
    надеюсь, что автор только в статье создаёт себе сложные препятствия, которые героически преодолевает. иначе могу только посочувстовать.
  • 0
    Все распространенные операционные системы (возможно, кроме некоторых негражданских и риалтайм систем) фактически основаны на ОС UNIX, содержат множество подпрограмм, подсистем, разработанных на/для этой системы или заимствуют идеи созданные, как ни крути, силами академической науки и в рамках Unix.
    Почти все писалось на unix

    А то, что за 50 лет основная концепция системы не устарела, а обросла лишь множеством надстроек/возможностей (и продолжает) работать во множестве сфер — все это говорит, скорее, в пользу системы.

    • +2
      Все распространенные операционные системы (возможно, кроме некоторых негражданских и риалтайм систем) фактически основаны на ОС UNIX

      Windows? POSIX там только сбоку прикручен.
      • +2
        Будете удивлены, но «И ты… Брут!». Современная Windows NT писалась совместно с IBM как раз таки на базе UNIX, в итоге после развала сотрудничества родилось две системы — Windows NT и OS/2. Которая умерла, если мне не изменяет память в 2012 году в связи со снятием с тех. поддержки, а до тех пор успешно использовалась в банкоматах. К слову файловая система HPFS поддерживалась вплоть до NT4.
        Именно из юникса у ядра NT очень много корней и Legacy наследия, которое сначала выпиливали, теперь возвращают. Фактически уникальность NT — это универсальное ядро, поверх которого работала подсистема Windows и Unix, а сейчас Windows и Linux.
        • +5
          Я может плох в истории, но один из, так сказать, главных дизайнеров Windows NT Дейв Катлер является одним из самых известных хейтеров Unix, и как раз делал все по-другому. Можно каких-то подробностей по Unix legacy в ядре NT?
          • +7
            Начнем с самого простого и очевидного (то что на виду), любое устройство является файлом, для доступа к устройствам используется виртуальная файловая система, драйверы рабоатют либо на уровне ядра (порты ввода вывода, DMA), люо в юзерспейсе как драйверы-фильтры (с хендлером файла устройства).
            Второе как следствие — драйверы фильтры, работающие с файловой системой.
            Третье — буквы дисков являются абстракцией и/или фикцией, точки монтирования маппятся как буквы дисков или прямо в файловую систему. При большом желании сейчас так можно маппить даже сетевые шары (экспериментально, но...)
            Символические и жесткие ссылки в ФС перепиливались и видоизменялись, но если мы посмотрим на атрибуты файловой системы NTFS мы увидим расширения UNIX, такие как пользователь, группа и режим доступа (они есть, на самом деле).
            Дальше — это организация архитектуры процессов и… Обработки сигналов. Да, я знаю что исторически в Windows используются сообщения, но часть сигналов осталась на уровне ядра, в юзерспейсе они регистрируются отдельными вызовами API, такие как Ctrl+Break или Ctrl+C.

            На самом деле действительно очень многие вещи были переписаны и в мире Unix на тот момент некоторых реализаций не существовало, того же автоматического пересканирования шины и так называемого autohotplug (подключение устройств на горячую — USB, PCMCIA, IEEE1394 и т.д.).

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

            Кстати, DNS в Windows Server это таки незначительно переписанный ISC Bind 9.
            • 0
              Я вот про буквы дисков и точки монтиования не понял. Точки монтирования позволяют примонтировать ФС где мне угодно, т. е. я контроллирую под каким именем будет известна та или иная партиция диска или та или иная виртуальная файловая система. В Windows у меня над этим контроля нет (на сколько я знаю). Где я не прав?

              Я не думаю что пользователь — это Unix специфичное расширение. Понятие пользователя было до Unix-а и нет ничего удивительно в том, что NTFS их хранит, аналогичная история с режимом доступа. Более того VFS — теперь совершенно привычная вещь для Unix, для Windows не совсем. Так что я бы не сказал, что Windows ФС это Unix legacy.

              Про архиетктуру процессов — слишком абстрактно, так что не могу никак прокомментировать. Само понятие процесса существовало и до Unix, интереснее что специфично от Unix-а взято.
              • +1
                > В Windows у меня над этим контроля нет (на сколько я знаю). Где я не прав?
                Есть, просто он спрятан от рядового пользователя (современные версии ОС я вижу очень редко, но мне кажется этот момент там не сильно изменился)
                • 0
                  Ну ссылка которую вы привели тоже не на самый первый NT ссылается (и не могу найти в статье информации о версиях NT, в которых эта фича поддерживается), так что нельзя утверждать что это Unix legacy. Вполне могу представить, что они это потом впили, дабы угодить особенно привередливым клиентам. Есть ли что-нибудь постарше?
                  • 0
                    Не знаю как в NT 3.5, но в Win2K и NT4 было тут: HKLM\SYSTEM\MountedDevices
              • +1
                В командной строке есть утилита diskpart, и в управлении компьютером — оснастка «Управление дисками». Windows Server 2012 (на базе исходников LVM, как указала MS) привносит Storage Spaces — запустите и откроете для себя много нового.
                Ссылка ниже показывает впервые появившуюся команду в юзерспейсе для монтирования дисков.

                Я имею в виду запись вида user:group , ну к примеру 0:0 7777 (root:root rwt,rwS,rws). В двоичном виде это три шестнадцатеричных слова.

                Можно я не буду вдаваться в особенности межзадачного взаимодействия в первых ядрах NT? :)
                Материал довольно большой, да и освящен довольно неплохо в книгах для разработчиков.
                • 0
                  Ну скажем так, LVM, даже если забыть про Windows, я бы не назвал Legacy — он не такой уж старый (1998, это уже linux 2.4, да и windows nt повяился несколько раньше, если мне не изменяет память) и не настолько уж типичный для Unix-ов в целом.

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

                  Меня интересует не интерфейс. Многие концепции на самом деле не специфичны именно для Unix-а и существовали до него. Меня как раз интересует то, что внутри, т. е. как они реализованы. Чтобы можно было ткнуть пальцем и сказать — вот это вы ребята сперли из BSD (как, например, некоторые считают про сетевой стек BSD). Не так уж много книг, которые покрывают эти части.
              • +3
              • 0

                Откройте в винде (XP или 7) "Управление компьютером", далее "Управление дисками", выберите какой-нибудь раздел и там "Сменить имя диска или путь к диску". Там можно удалить букву диска и назначить ему вместо этого путь, куда надо монтировать. Далее в винде есть ключ/ветка реестра MountedDevices, я вот тут писал: https://geektimes.ru/post/156749/

            • +2
              но если мы посмотрим на атрибуты файловой системы NTFS мы увидим расширения UNIX, такие как пользователь, группа и режим доступа (они есть, на самом деле).


              Это не так. Собственное в NTFS нет как таковых фиксированных аттрибутов, вместо этого есть понятие альтернативных потоков файла. В основном потоке данных содержится собственно содержимое файла, в альтернативных — все что угодно. Это могут быть разрешения (DACL), информация для аудита (SACL), сведения об источнике файла (например что файл загружен через Интернет) и вообще все, что угодно, включая POSIX-совместимые аттрибуты. Набор альтернативных потоков у каждого файла может быть свой.
              P.S. и ИМХО это очень красивый подход.
              • –1
                Собственное в NTFS нет как таковых фиксированных аттрибутов

                Только для чтения, скрытый, системный, архивный, сжатый, разрежённый, индексируемый, зашифрованный. Это как минимум, и это атрибуты, а не альтернативные файловые потоки.
                P.S. и ИМХО это очень красивый подход.

                И не используется. В десятке используются костыли отдельная база данных с разрешениями POSIX.
                К тому же в этом подходе есть проблемы- все потоки теряются при копировании на ФС без их поддержки, например, FAT. Досталось это при обеспечении совместимости с OS/2 в стародавние времена. Ну и у EXT3 и некоторых других ФС Linux есть похожие механизмы.
                • 0
                  >К тому же в этом подходе есть проблемы- все потоки теряются при копировании на ФС без их поддержки, например, FAT.

                  А при копировании с ext4 на fat сохраняются атрибуты?
                  • 0
                    Нет, это общая проблема.
                • +5
                  Не совсем так. Тут есть определенная путаница с терминами. В NTFS термин «аттрибут» используется для записи с данными, в этом плане данные файла и альтернативные потоки тоже являются аттрибутами. Указанные вами аттрибуты хранятся как часть аттрибута $STANDARD_INFORMATION, т.е. $STANDARD_INFORMATION от альтернативного потока отличает только тип аттрибута, альтернативные потоки имеют тип $DATA.
            • –2
              Начнем с самого простого и очевидного (то что на виду), любое устройство является файлом,

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

              но если мы посмотрим на атрибуты файловой системы NTFS мы увидим расширения UNIX, такие как пользователь, группа и режим доступа (они есть, на самом деле).

              ACL в NTFS были изначально, ещё до того, как появились эти самые «расширения UNIX», и до того юниксоидам приходилось извращаться с политикой доступа через rwxrwxrwx, что намного менее гибко. И причём тут символические и жёсткие ссылки?

              Дальше — это организация архитектуры процессов и…

              Да-да, вот тут тоже интересно, треды были в NT опять таки изначально, а более-менее стандартное NPTL в юниксах появилось сильно позже. До этого считалось, что дискретизации шедулера на уровне процессов и так всем хватит, ибо нефиг.
              • +2
                ACL в NTFS были изначально, ещё до того, как появились эти самые «расширения UNIX», и до того юниксоидам приходилось извращаться с политикой доступа через rwxrwxrwx, что намного менее гибко. И причём тут символические и жёсткие ссылки?

                Верно. ACL привнесли ребята из DEC/ VMS команд, ACL были в RSX-11 на PDP.
          • +4
            Ко всему описанному добавлю: современные исполняемые файлы под NT (Portable Executable) основаны на COFF (даже заголовок его наследуют).
        • +3
          Я давно говорю, нет, я кричу сделайте в школе и вузах хоть краткий курс истории науки.
          Новые поколения считают, что все новое появляется вдруг, само по себе. А старое было плохо и т.д., и т.д.
          Но мои слова летят в пустоту, все хотят прикладных знаний и быстрых прорывов.
        • +3
          Современная Windows NT писалась совместно с IBM как раз таки на базе UNIX

          Вообще-то там корни идут совсем в другую сторону.
          Фактически уникальность NT — это универсальное ядро, поверх которого работала подсистема Windows и Unix

          Там может работать что угодно, была бы нужная подсистема. Изначально вообще никакой win подсистемы там не было, её впилили потом, как и поддержку архитектуры семейства i386.
          • +1
            По первому проясните подробнее, где я заблуждаюсь?

            По второму пункту согласен полностью. Хоть историческую статью всем Хабром пиши. С миру по нитке — общая картинка в целом.
            • +2
              По первому проясните подробнее, где я заблуждаюсь?

              Основным разработчиком NT был Дэвид Катлер, который перешёл из DEC, где пилил VAX и VMS. Из-за этого даже судились.
              Хоть историческую статью всем Хабром пиши

              Да уже есть, нужно просто погуглить.
        • +2
          Вобще-то нет, Катлер и его команда пилили VMS в Digital, поэтому в первых НТ было всё-таки больше от неё, чем от чего-то позиксного.
  • +3
    Или некий аналог реестра

    gconf/dconf, разве нет? Да и транзакционную sqlite некоторые приложения используют. А благодаря тому что конфиги отдельной программы потенциально находятся во вполне определённых директориях становится воможным ПОЛНОЕ удаление приложения так, что система вернется к состоянию когда приложение не было установлено (в Windows большинство приложений не могут собственную папку удалить из Program Files при деинсталляции, не говоря уже о жести с происходящим в реестре).

    • +3
      Необязательно же делать как в винде. И, как мне кажется, ничто не мешает пакетному менеджеру заниматься не только файлами, но и реестром. Тогда после удаления софта ничего не останется.
      В винде проблема с удалением именно в том, что у каждой программы свой деинсталятор, а разработчики деинсталятора забивают на качество его работы.
      По парсеру на конфиг — действительно проблема и излишние сложности, множество поводов выстрелить себе в ногу.
      Реестр же позволяет все данные хранить в унифицированном виде, что несомненно хорошо, тут я полностью согласен с автором.
      • 0
        К сожалению, кое-что мешает пакетному менеджеру заниматься конфигами. Пакетный менеджер знает только то, что ему дано в описании «пакета» (программы), т. е. если программа динамически создает конфиги (например, отдельный конфиг для каждого user-а в /home) и никак не сообщает о них пакетному менеджеру, то и удалить эти конфиги он не может. Т. е. фактически проблема сводится к тому, что для программы должен быть сделан средствами ее создателей адекватный деинсталятор — и пакетный менеджер сам по себе эту проблему решить не может.

        Но как лирическое отступление, например, пакетный менеджер apt (Ubuntu/Debian/etc) поддерживает команду purge, которая пытается удалять программу вместе с ее конфигами. Так что по мере возможностей, некоторые более или менее популярные пакетные менеджеры, по крайней мере в Linux, пытаются заниматься конфигами.
        • 0

          Не пытаются, а успешно занимаются. Но как вы правильно заметили, только системными, которые устанавливались с пакетами и, возможно, менялись пользователем. Но я ни разу не видел приложения, которые удаляют конфиги из домашней папки. К счастью есть всего несколько папок и несколько веток в dconf где с 99% вероятности будут конфиги приложения. Почистить это совсем не сложно.
          Хотя (в теории) можно повесить хук на удаление и подчищать даже пользовательские конфиги, но, повторюсь, ни разу такого не видел.

          • +9
            В домашней директории пользователей лежат не конфиги, а файлы пользователей. Да, это может быть какой-нить .softname/config, но это файл пользователя, который пользователь или явно написал сам, или натыкал в графическом меню программы softname(есть конечно вариант что он «автосгенерировался» при первом запуске). И пользователь может сделать что-то типа «apt remove softname && apt-add-repository… && apt update && apt install softname» и ожидает увидеть новую версию softname, поставленную из «правильного» ppa, но со своим старым конфигом (я например уже лет 10 таскаю ~/.purple/, ~/.mozilla/ и ~/.thunderbird/ по разным ноутбукам, дискам и ОСям).
            И я считаю что трогать данные пользователя никогда не нужно. Пользователь может потом захотеть снова поставить тот же софт, может захотеть перенести конфиг на другую машину или просто сохранить конфиг в какой-нить git на всякий случай).
            • –1
              В домашней директории пользователей лежат не конфиги, а файлы пользователей.


              Э?
              А что лежит в ~/.config?
              • +1
                файл пользователя, который пользователь или явно написал сам, или натыкал в графическом меню программы softname
                • 0
                  Нет, это дефолтное место для XDG-конфигов пользователя.
                  Причём, в принципе — могут порождаться программами — или ставиться из пакета по-умолчанию.
        • 0
          Но как лирическое отступление, например, пакетный менеджер apt (Ubuntu/Debian/etc) поддерживает команду purge, которая пытается удалять программу вместе с ее конфигами. Так что по мере возможностей, некоторые более или менее популярные пакетные менеджеры, по крайней мере в Linux, пытаются заниматься конфигами.

          Он удаляет только те конфиги, что были созданы на этапе установки пакета, зачастую это дефолтные конфиги в том же /etc или /etc/default, которые есть в описании пакета. Это делается для случаев, когда дефолтные конфиги были изменены юзером, затем сама програма была remove, а потом вдруг понадобилась обратно.
          За динамически генерируемым конфигами, например в том же /home/.config apt не следит.
          • 0
            Я ровно это и написал. Что ваш комментарий добавляет к моему или оспаривает в нем?
            • 0
              Часть про purge довольно скомканная и после описания проблемы динамических конфигов выше создаётся впечатление, что purge — панацея и умеет в удаление и их, а не только системных.
              • 0
                Часть выше части про purge вполне подробно и даже с примером (абсолютно эквивалентным вашему) объясняет почему пакетный менеджер не может впринципе следить за всеми конфигами. А часть про purge содержит слова «пытается» и «по мере возможностей» — очень не похоже на описание панацеи.
        • 0

          В том-то и дело, что программа не должна лезть куда-либо за пределы своей песочницы. Пусть пишет в свои ./user/ и ./local/ а система уже разберётся что в эти директории примонтировать.

          • +1
            Вы предлагаете пакетному менджеру еще и в качестве песочинциы для всех программ выступать или что? Я не понимаю, как то, что программа «не должна», относится к пакетному менджеру и его возможности/невозможности удалять конфиги? Он что может как-то заставить программу не делать, то что она делать не должна?
            • 0

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

              • +2
                Т. е. не только пакетный менеджер но еще и пеочница, которая для каждого приложения отслеживает, что оно в runtime-е делает? Вам не кажется, что вы слишком многого хотите от пакетного менеджера?

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

                Более того, я не думаю, что у пакетного менджера (предполагая что это просто приложение, а не часть ядра) будет достаточно возможностей, чтобы выполнять все необходимые проверки эффективно.
                • –3

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

                  • +4
                    1. Я не зацикливаюсь на термене. Разговор был изначально о пакетных менеджерах и о том, что они могут делать с конфигами — я просто придерживаюсь темы разговора, чтобы не вводить никого в заблуждение.
                    2. Docker — это не ОС.
                    3. Docker образ содержит образ ОС. Этот образ все еще содержит кучу конфигов, которые нужно настраивать и править.
                    4. Docker ничего не контроллирует, он пользуется средствами ОС (контейнеры и cgroups).
                    5. Делать для каждого отдельного приложения свой контейнер — это просто overkill. Представьте что вы git, g++, make/CMake/Scons/etc все поставили в различные контейнеры — как этим вообще пользоваться?
                    • –4

                      Вы не поверите: http://rancher.com/rancher-os/

                      • +3
                        Не поверю чему? Я знаю об этом проекте, что из сказанного мной этот проект опровергает?
                        • –1

                          Что не OS, что оверкилл, что ничего не контролирет и пр. Или за ОС вы только ядро считаете?

                          • +3
                            1. Обратите внимание там написано RancherOS, а не Docker. Docker — это часть RancherOS.
                            2. С чего вы взяли, что не оверкилл? Более того, вы можете заметить, что Rancher OS не использует отдельный контейнер для каждого приложения.
                            3. Docker не контроллирует, он просит ядро ОС контроллировать (ядро — один компонент ОС, Docker — другой).
                            4. Нет я не считаю только ядро за ОС, как и не считаю только Docker за ОС, на что и пытаюсь вам указать.
                            • –4

                              Думаете суть бы изменилась, если бы её назвали DockerOS? Или если бы функционал докера перенесли в ядро?


                              А судя по картинке — использует.


                              image

                              • +1
                                1. Дело не в названии, а в том, что Docker сам по себе работать не может — ему нужно ядро с определенными сервисами. Есть Docker и есть ядро — это разные компоненты, с разными обязанностами.
                                2. Если бы функционал Docker-а перенесли в ядро, то все баги Docker-а стали бы исполняться в привелигированном режиме, в дополнение к багам самого ядра — как минимум пострадало бы качество (разделение на сравнительно независимые части — довольно фундаментальный инженерный принцип).
                                3. А вы не по картинкам смотрите, а запустите ее у себя. Вы увидите, что стандратные утилиты (cat, grep и тд и тп) — самые обычные процессы, а не контейнеры.
                            • +4

                              Может — вообще имело смысл хранить все программы их модули, конфиги и библиотеки, в базе данных с версионированием, зависимостями, горячей заменой в памяти и прочими полезными вещами.
                              Но, во времена создания юникса всё это можно было реализовывать только в мечтах — по причине недостаточного технического и научного уровня тех лет. А без исходного кривого юникса не было бы современной идеи свободного ПО и самого ПО.
                              Поэтому в историческом плане юникс с потомками и язык С — все таки вещи положительные.
                              И, самое главное, опыт их применения и собранные грабли дают понимание того, как не надо в будущем делать и использовать ОС и языки — особенно, огромными группами разных людей и организаций, с разными целями и возможностями, никогда не пересекающихся между собой в пространстве и времени, расходясь на тысячи километров и десятилетия.
                              Ни один язык программирования или иная технология пока даже не пытается взвалить на себя такую неподъёмную задачу, но, сделать это все равно кому то когда то придётся — хотя бы для того, чтобы попытаться перестать терять деньги от замены дублирования старого кода.
                              А, так как отправить на пенсию существующие технологии пока не получается, то, наверное, значит, что предел их прочности ещё не достигнут.

                              • 0
                                Я не очень понял как это относится к моему комментарию непосредственно. Но вообще программы, модули, конфиги и библиотеки уже сейчас можно хранить с версионированием, но не в БД, а в подходящей файловой системе (Btrfs и ZFS поддерживают дешевые snapshot-ы — перед изменением/установкой/удалением создаете snapshot и, если что-то пошло не так, просто откатываетесь к этому snapshot-у). Для версионирования конкретно конфигов можно просто использовать git/svn/etc, но это, скорее, для конфигов, которые мы пишем сами.

                                Но даже с учетом всего выше сказанного, не понятно, каким образом версионирование позволит пакетному менеджеру узнать о конфигах, о которых ему никто ничего не сообщал и удалить их?
                • 0

                  Советую почитать о flatpak и snap

      • +3
        В винде проблема с удалением именно в том, что у каждой программы свой деинсталятор, а разработчики деинсталятора забивают на качество его работы.
        Такие люди и на качество самого приложения обычно тоже забивают. Например, положат в виндовом реестре в HKLM то, что должно лежать в HKCU, а потом ещё пишут свой собственный велосипед для реализации HKCU внутри узла из HKLM.

        Бардака нет только там, где он концептуально невозможен. И даже в таких системах кто-нибудь обязательно изловчится по шву чем-нибудь аккуратно мазнуть по незнанию или простой дурости.
      • 0
        В винде проблема с удалением именно в том, что у каждой программы свой деинсталятор, а разработчики деинсталятора забивают на качество его работы.

        Это не в винде проблема, это в криворуких программистах, которые не могут в MSI.
        • +2

          Если бы у этого MSI было чуть-чуть по-больше документации… Потому что сейчас "не могут в MSI" даже сами Microsoft.


          Посмотрите на те же VC redistributable packages. Хоть одна доступна в формате MSI?


          PS Привет пакету, кажется, от 2008, который при установке выдавал ошибку если он был уже установлен в системе :)

          • +1
            у 2008 была другая более мерзкая проблема — он срал не в %TEMP%, а в корень самого свободного диска — то есть во-1х, кто тебя, сволочь, просил? а во-вторых, если у тебя например MacDrive или аналогичная приблуда, с дисков которой НЕЛЬЗЯ запустить бинарники — то всё, приплыли.
    • +2

      Да бардак с конфигами и линуксе и в винде. Где-то sqlite (читай — у каждого приложения свой формат в виде схемы БД), где-то gconf, где-то ini, где-то xml.


      Разрабатывал программы (под windows), где одновременно используется 3-4 вида конфигов. Привести их к единому реестроподобному формату, кстати, не получилось. Файлы конфигов, конечно, можно удалять, но этот зоопарк всё-таки не выглядит "чисто".

      • +7

        Мне как пользователю совершенно не важно какой там конфиг. Главное чтобы я мог его очень легко найти в совершенно конкретном месте и удалить при желании (чтобы сбросить настройки или после удаления приложения). В Windows у меня этого никогда не получалось. Начиная с рядовых приложений разного калибра, и заканчивая компонентами с обновлениями самой ОС. Система постоянно патологически накапливает мусор.

    • 0
      gconf/dconf, разве нет?

      Единственное, еще бы договорились, который из них оставить. Вот в упор не понимаю, зачем их ДВА.

      • +1

        Dconf вроде как более новый (на диске данные в бинарном формате хранит), а gconf это legacy (там данные хранятся в xml файлах). Все новые приложения используют именно dconf.

        • 0
          А разве это не фича Гнома?
    • 0
      в Windows большинство приложений не могут собственную папку удалить из Program Files при деинсталляции

      У меня вот на сервере болтается в etc каталог Apache2. Сам апач давно удалён, и этот каталог удалялся, но он восстанавливается при обновлении php7.0-fpm.
      Логика? Нет, не слышал.
      • +3

        Установили php7.0-fpm, в папку apache2 скопировался его конфиг для этого веб-сервера. Удалите пакет — удалится и директория. Всё под контролем менеджера пакетов. Да, кривовато слегка, но всё вполне логично.

        • –1
          Ну а посмотреть, что никакого апача нету, и конфиг для него- просто мусор, apt конечно не может.
          • +1

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

            • 0
              Вот решение этого через хуки- это и есть «кривовато». Почему бы не сделать в пакетном менеджере поддержку опциональных зависимостей со своим деревом файлов, которое нужно копировать, когда оно есть, и не нужно, когда эта зависимость не установлена? Заодно эту зависимость можно разрешить в ситуации после установки основного пакета, когда ставится опционально зависимый, чего не сделаешь через хуки.
              • +2

                Так есть опциональные зависимости, кто вам сказал что их нет:) Всё зависит от того, как мейнтейнер соберет пакет. Ваш пакет собрал таким образом. Кривовато, но ничего страшного.

          • +2
            а если вы сделаете «apt install php7.0-fpm; apt install apache2»? первая команда видит что апача нет и конфиг дня него не кладет, вторая команда ставит апач, а конфига для php7-fpm нет, тут нужно либо усложнять пакетный менеджер «списками кросс-зависимостей файлов» и после установки апача вызывать что-то типа «перераскладывания примеров конфигов для php7-fpm и всех остальных, у кого могли быть примеры конфигов для апача» при этом попутно решая что делать с «вручную исправленными конфигами». К тоже же кмк идеологически неверно при установке апача как-то реконфигурировать совершенно другой пакет. Да и к тому же не очень понятно чем вам мешает лишняя директория в /etc. Все таки это не так критично влияет на производительность, как замусоренный реестр в windos.
            • +1
              тут нужно либо усложнять пакетный менеджер «списками кросс-зависимостей файлов»

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

              Вообще- то замедление ОС из-за реестра является мифом. Так как реестр по сути является базой данных, то его объём никак не влияет на скорость его работы.
              • +1
                Не мешайте людям раз за разом использовать «Чистильщики реестра» и «Ускорители компьютера», чтобы потом жаловаться, что ничего не работает. Это их выбор
                • 0
                  Конечно это их выбор, но они носятся с утверждением «Винда глючит и тормозит, я каждые два месяца её вынужден переставлять, реестр загажен».
    • 0

      Как в Windows, так и в UNIX-системах можно полностью удалить любое приложение. При условии, что разработчик позаботился о корректном удалении. И зачастую при условии, что этим приложением пользовался только один юзер (иначе придётся во всех юзерских папках потом вручную удалять ошмётки).


      В Windows это делается через панель управления, в UNIX-системах — через менеджер пакетов либо (если собирали из сорцов) с помощью make uninstall.


      Другое дело, если разработчик накосячил с удалением. Тогда уже для винды нужно использовать всякие там full remover, а в случае с UNIX — всякие там checkinstall и пр.


      И в случае обоих систем (Windows и UNIX-подобное) если вам нужна абсолютная гарантия полного удаления пакета — восстанавливайте ОС из бекапа. (Замечу, что NixOS [как минимум в теории] поддерживает абсолютное удаление; так, как если бы система была восстановлена из бекапа; потому что там состояние всей ОС определяется всего небольшим количеством конфигов)

      • –1
        не видел ни одного приложения под win, которое удаляется ПОЛНОСТЬЮ, не оставляя файлов/записей в реестре.
        • 0

          А я сопровождаю четыре таких, и еще два пишу :)

        • 0
          Наоборот, на мой взгляд, редкость, когда что-то остается. Это очень субъективно, зависит от набора используемых программ.
  • +9
    Теперь я примерно представляю как мог размышлять Поттеринг создавая свои решения. Вот это все «надо везде использовать JSON, XML и бинарные форматы, а потом просто их дополнительной программкой в человеческом виде выводить».
    • +8
      Добавление в основные утилиты ввод/вывод JSON сильно бы упростило использование этих утилит со скриптовыми языками. Не пришлось бы парсить вывод самостоятельно
      • –4

        Лучше всё же формат Tree, он и машиной и человеком легко читается, чего не скажешь о JSON и XML.

        • +1
          Не лучше, т.к. JSON в любом языке есть, а Tree где-то брать надо
          • +1

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


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

            • 0
              Эти структурированые текстовые форматы суть одно и тоже, плюс-минус «множество восхитительных функций»(с) сверху. Смысла менять одно на другое особого нет. Есть структура и хорошо. Впринципе (для вышеописанной задачи) и ini сгодится. Но JSON популярней. Еще можно XML — он тоже есть почти везде.

              Кстати, насчет ini… Мне лично очень понравился toml. Тоже человекочитаемый. Но, в отличие от, реально используется, хоть и в узкой нише (конфиг менеджера пакетов Cargo)
              • 0

                Что значит "менять"? Сейчас приложения выдают плоский текст без какой-либо структуры. Так что вкручивать любой формат одинаково сложно и выбирать нужно не по принципу "для какого там формата есть либы для большего числа языков" (ответ — XML, но слишком громоздкий во всех смыслах), а по принципу "какой формат лучше подойдёт", а либы под разные языки быстро появятся, если формат не такой сложный, как YAML, последней версии которого, до сих пор почти нигде нет.

                • +1
                  > Что значит «менять»?
                  Менять JSON на Tree
                  • 0

                    С каким ключом вызывать ls чтобы получить JSON?

            • НЛО прилетело и опубликовало эту надпись здесь
              • 0

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

        • +1
          Tree выглядит интересно, но как сказал Jaromir, его надо где-то брать. Можно, конечно, поставить конвертер по дороге, но это уже костыль.

          В нашем мире существует неимоверное количество различного легаси и заставить что-то переписать под новый формат потому что он лучше просто не выгодно экономически.

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

          Я все это говорю к тому, что переход на новое возможет только тогда, когда возможности старого абсолютно исчерпаны и написание костыля обойдется дороже, чем просто взять и написать заново.
          • 0
            Неужели в IT всё оценивается чисто экономически? А как же красивый код, идеальная архитектура, тяга к прекрасному, и прочая ерунда)
            • +1
              Это тоже имеет экономические последствия на большом отрезке времени
            • 0
              Неужели в IT всё оценивается чисто экономически?

              Это загнивающий капитализм )
              А как же красивый код, идеальная архитектура, тяга к прекрасному, и прочая ерунда)

              Все это может быть выгодно экономически, но нередко живет за счет этнузиазма или лени мучаться с костылями к первоначальному говнокоду.
              • +1
                Я скорее имел в виду что-то другое. Понятное дело, что фирме надо продавать софт, чтобы существовать, а программистам хотелось бы получать зарплату, чтобы питаться не святым духом. Но можно же совмещать необходимое с приятным. Писать хороший код, не юзать костыли, и т. п.)

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


                Меня вот это удивило. Грамотный системный архитектор так ведь делать не станет. А заранее продумает всё так, чтобы было хорошо и красиво. А если уже продумано неправильно, и поезд ушёл — исправит ошибку как можно скорее, а не дожидаясь того момента, когда «всё, катастрофа, поддерживать это не реально». Имхо
                • 0

                  Исправить ошибку как можно скорее можно только когда поезд еще не ушел.

                • 0
                  Грамотный системный архитектор так ведь делать не станет. А заранее продумает всё так, чтобы было хорошо и красиво. А если уже продумано неправильно, и поезд ушёл — исправит ошибку как можно скорее, а не дожидаясь того момента, когда «всё, катастрофа, поддерживать это не реально». Имхо

                  Если это стартап, то ситуация может быть следующая:


                  1. Быстро нужно дэмо, чтобы показать концепцию инвесторам
                  2. Инвесторов не волнует насколько стремно будет написан код — пусть уже начнет деньги приносить
                  3. Код пишется поверх дэмо без какого-либо дизайна
                  4. Для новых фич пишутся костыли, потому что дэмо этого не предусматривало
                  5. Дизайна все еще нет, так же как и архитектора, который бы этот дизайн написал
                  6. Количество костылей превышает критическую массу и добавление фич больше невозможно
                  7. Частично пишется дизайн каких-то модулей и куча говнокода приводится к нему
                  8. Добавляются новые фичи и костыли для них до очередного витка переделок

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


                  З.Ы. Добро пожаловать в мой мир

                  • 0
                    А что мешает потратить неделю-две на дизайн до пункта 2?.. Там-то никто не гонит :)

                    Если проект очень сложный — может, займёт и дольше, но мы же про относительно простые стартапы, верно?

                    Ну или как вариант — заморозить виток новых фич, и недели 2-4 заниматься только рефакторингом и устранением костылей, а пользователи типа переживут. Всё-таки стабильность дороже :) А то начнёт всё падать из-за багов — клиенты точно разбегутся.
                    • 0
                      А что мешает потратить неделю-две на дизайн до пункта 2?.. Там-то никто не гонит :)

                      Ничего, кроме торопливости начальства и ТЗ с детализацией уровня "как-то так должно работать".


                      Если проект очень сложный — может, займёт и дольше, но мы же про относительно простые стартапы, верно?

                      Ну, в том случае о котором я говорю, проект с огромным количеством разного функционала. Не назвал бы его простым.


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

                      • 0
                        Я почему-то думал, что в стартапе разработчики — сами себе начальство. Ну и кто-то один главный. Так только в кино бывает? :)

                        Потому и писал, что к пункту 2 времени в теории — неограниченное количество, если конечно нет конкурентов с той же идеей.
                        • 0
                          Я почему-то думал, что в стартапе разработчики — сами себе начальство. Ну и кто-то один главный. Так только в кино бывает? :)

                          Ну, по-началу, оно может так и есть, но со временем количество людей растет и появляются начальники и стартап становится нормальной компанией. Правда бывают стартапы-переростки: начальники есть, а порядка нет. Тогда-то и начинается беда.


                          Потому и писал, что к пункту 2 времени в теории — неограниченное количество, если конечно нет конкурентов с той же идеей.

                          А как же теория спелых яблок?

                          • 0
                            А что это?) Не слышал про такую.
                            • 0
                              Кратко — «куй железо, пока горячо». Или «седлай волну, пока не ушла».
                              • 0

                                Мне казалось, что popov654 шутит...

                                • 0
                                  Гугл про такую ничего не знает)) А что не знает Гугл, то я не могу знать тем более. Какие тут шутки…
                                  • 0

                                    Странно, что гугл не знает этого.


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


                                    Собственно, если есть новая идея, то вероятно кто-то уже над ней работает.

      • +2
        > Добавление в основные утилиты ввод/вывод JSON сильно бы упростило использование этих утилит со скриптовыми языками.
        И сильно увеличило бы время на парсинг/генерацию этого самого JSONа. Я не говорю, что текст, это всегда хорошо, но да, я действительно предпочту текст, когда мне нужно распарсить текстовый файл на 500 МБ, написав скрипт для этого всего за 10 минут.
        Пример из недавнего прошлого: Задача сводилась к поиску нескольких тысяч ключей по несортированному дампу с порядка 8 млн записей. К слову grep (вызов в цикле из bash скрипта) позволял делать порядка 10 проходов в секунду (!), файл лежал в горячем кеше после первого прохода.
        Другие языки (пробовал на php7 и python) с задачей справляются в 3 раза медленнее, даже если предварительно прочитать файл в RAM, и только специализированная БД (redis в моем случае) позволила увеличить скорость в 10 раз.
        • 0

          А в этих "других языках" вы использовали какие-то индексные структуры? По-хорошему этот дамп нужно впихнуть в любую БД, построить индексы и искать по ним. В redis, наверно, так и получилось. sqlite, думаю, тоже подойдёт (да хоть MS Access, бывало и такое).


          grep использует всякие продвинутые алгоритмы строкового поиска, которые вряд ли есть в стандартных библиотеках php/python/etc. Вручную быстрее вряд ли напишете.

          • 0
            Не использовал, опять таки, не было задачи. Про продвинутые алгоритмы в grep вы правы, но первоначальная идея была в том, что он все-равно читает файл каждый раз последовательно и всегда до конца, но полученная скорость grep меня поразила.
  • +33
    Вы только представьте! Вот допустим, нужно удалить все файлы в текущей папке с размером, большим 1 килобайта. Да, я знаю, что такое надо делать find'ом. Но давайте предположим, что это нужно сделать непременно ls'ом.

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

    • +7
      Вот прямо с языка сняли. Меня всегда удивляли авторы, которые выискивают неведомые редкие кейсы, жалуются на сложность( но не невозможность) их решения, а потом поносят систему в целом. Да в никсах можно вообще все сломать командой из нескольких символов ( привет gitlab) и что ж теперь? Реестры писать? Да ну нахрен!
    • +1
      На самом деле подобная хрень может возникнуть :) Как-то раз мне в руки попал роутер с каким-то очень обрезанным линуксом на борту и там не было даже улитилы dd, не говоря уже о такой замудреной вещи как find.
      • +3

        Так в данном случае это как раз прекрасно, что система позволяет забить гвоздь микроскопом (если очень хочется, или религия не позволяет молоток использовать, или старшина приказал). Но тут уж не стоит удивляться тому, что сделать это сложнее, чем молотком.

      • 0
        И вы конечно же сделали вывод что все unix системы полный отстой и куча костылей? Я надеюсь нет.
    • +1

      Однажды постучался я по ssh на девайс, ввожу find . -iname "*.jpg" -exec cp {} ./ \;, а он мне такой: а нету тут find-а!

  • +5
    Как это развидеть?
  • +4
    Спасибо, не дочитал.
  • +12
    Судя по контексту статьи и постоянным переходам на личности, автор считает всех идиотами, а себя видимо самым умным. Поэтому даже не дочитал. Подача материала на 2.

    Статья написана наскоро, «полировать» дальше не хочу, скажите спасибо, что написал.

    Спасибо, не пиши больше.
    • +17
      Статья написана вполне нормально. Для тех кто реально понимает и на практике с этим сталкивался, все понятно и знакомо.
      А если писать более подробно, то будет не статья а многотомное собрание сочинений.
      • –1
        особенно словечки sic! Бугога и т.д., реально на практике часто сталкиваюсь, все понятно и знакомо.
        Тьфу!
    • 0

      @DexterHD, nightvision, стиль статьи, слова "бугога" и пр. — это типичное явление в американских блогах, в том числе в переводах статей из американских блогов на Хабре, почитайте их (хотя у меня не перевод). Особый стиль нужен, что "встормошить" читателя, который и вправду фанатеет от UNIX. Сказать ему, так сказать: "Проснись, UNIX давно устарел!"

      • 0
        А, так вот почему всю статью было впечатление, что это чей-то перевод…
      • –1

        Посмотрите мой коммент выше, DexterHD (я не уверен, что парсер Хабра вас с первого раза пинганул)

    • +2
      автор считает всех идиотами

      А что, наш социум логичен и рационален everytime?
      Статья написана наскоро, «полировать» дальше не хочу, скажите спасибо, что написал.

      Это тонкий сарказм, отсылка к философии unix, а не к статье.
      • 0

        @basilbasilbasil, kirillaristov, сарказм, отсылка к философии UNIX? Что? А, вон оно что! :) В общем, нет, я об этом не подумал, это было сказано в прямом смысле

        • 0
          сарказм, отсылка к философии UNIX? Что? А, вон оно что! :)

          Так и рождаются «синие занавески»
          Скрытый текст
          image
        • –1

          Посмотрите мой коммент выше, basilbasilbasil, я не уверен, что парсер Хабра вас пинганул

        • 0
          safinaskar, ок, главное — легло по смыслу как полагается.
  • +11
    Полностью согласен с автором. Я не такой спец по юниксам, но сталкиваться приходилось достаточно. Кривизна make и shell сразу бросается в глаза. Кривизна препроцессора С/С++ и отсутствие в них модульности — тоже (хотя пишу на С/С++ как основном языке уже много лет).
    С другой стороны многие концепции в юниксе очень удачны и даже гениальны. Есть фундаментальные вещи из линукса которых очень не хватает в винде. И наоборот.

    А проблема — в инертности мышления, да и в инертности общества вообще.
    Разработали — работает как-то — а зачем трогать и улучшать? Мозг-то привыкает к любым костылям.
    И в результате может и есть где-то системы, лучшие (или хотя-бы потенциально лучшие) чем Unix (да и чем Windows, чего уж там) — но кто о них знает? А проект сдавать завтра, а инфы по этим новым системам кот наплакал — зато по линуксу и винде гигабайты статей и обсуждений на разнообразных сайтах и форумах, куча специалистов в совершенстве знающих любые костыли и готовых помочь…

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

    Так, вместо make давно бы уже перешли на qbs. Что мешает корпорациям, осуществляющим основной вклад в разработку того же линуса, перейти на эту технологию? Если там чего не хватает — ну так оно и выяснится, сформировали бы консорциум, подумали бы все вместе. И постепенно вытеснили бы make. Но нет — оно же «и так работает»… печально все это.
    • +2

      Назовите хоть одну вещь из Windows, которой не хватает в нынешних *NIX?


      Also есть scons.

      • +2

        ACL? Из-за них, кстати, файлы WSL из-под винды трогать не надо.

        • +1
          Есть Posix ACL. Можно подробнее что в Window-ых ACL есть, чего не хватает в Posix ACL?
          • 0

            И в какие популярные дистрибутивы он входит «из коробки»?


            Такие доводы напоминают Джаббер: там тоже есть 100500 расширений, только все нестандартные и разной степени костыльности. И где этот джаббер? Все сидят в Вотсапе или Телеграме.

            • 0
              В ubuntu они есть по-умолчанию, другое дело, что чтобы они начали работать их нужно настроить (но простите, настройка ACL по-умолчанию — это какой-то странный зверь, что он и кому будет разрешат/запрещать?).