Можно ли писать скрипты на C++? +46






Недавно пришлось мне опять/снова погрузиться в чудесный мир программирования Linux скриптов. В принципе, дело не очень хитрое, но поскольку мне попадаются такие задачи не часто, то каждый раз изучаю заново. Знаю точно, что завтра многое забуду и через месяц опять буду гуглить, как сделать то или это. Проблема еще оказывается в том, что зачастую не пишешь скрипт заново, а модифицируешь существующий, уже написанный кем-то. А он может быть не bash, а sh или еще что-то… Различия в синтаксисе есть, что работает в sh по идее должно работать и в bash, но не всегда наоборот. А если там dash или ash? Я не знаю… Различия в этих скриптовых языках все же есть, и они сбивают с толка. Ну и конечно, лично для меня, вишенка на торте, когда скрипт вызывает какой нибудь sed или awk и там такие параметры в командной строке, что смотришь на них и диву даешься. Понятно, что это все зависит от квалификации программиста, но вот у меня не все в голове помещается. И вот сейчас мое терпение лопнуло и я подумал, что отныне хочу попробовать писать скрипты на c++…

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

Итак, мысль очень простая. Я хочу писать c++ скрипты так же, как пишутся обычные скрипты, то есть первая строка скрипта должна содержать shebang и указание на путь к «интерпретатору»:

#!/bin/c++

Последующие строки скрипта будут просто обычной программой на c++.

Я должен подготовить «интерпретатор» скрипта c++. Написать его можно на чем угодно, да хоть на bash (это в последний раз, хотя не точно). Конечно он будет не интерпретатором, а компилятором.

Вот что у меня получилось:

#!/bin/bash

msg_file=/dev/null
#msg_file=/dev/stdout

tmp_path=$HOME"/.cache/c++/"
mkdir -p $tmp_path
tmp_file=$1".c++"
exe_file=$1".bin"
if test $1 -nt  $tmp_path$exe_file; then
    echo "Need to recompile.." > $msg_file
    tail -n +2 $1 > $tmp_path$tmp_file
    eval "g++ -o $tmp_path$exe_file $tmp_path$tmp_file > /dev/null 2>&1"
    if [ $? -eq 0 ]
    then
	echo "Compiled ok" > $msg_file
    else
	echo "Compile error" > $msg_file
	exit 255
    fi
fi
eval "$tmp_path$exe_file $@1"

Этот скрипт делает все, что нужно. В качестве временной папки я выбрал папку ~/.cache/c++. В эту папку будет копироваться исходный скрипт, но без первой строки с shebang. Делается это командой tail. Имя нового файла будет как у исходного скрипта, но с расширением c++. В той же самой папке будет собираться бинарник, с расширением .bin. Но, сперва, конечно, делается проверка «if test» на время создания бинарника. Компиляция происходит только если существующий бинарник устарел по времени по отношению к исходному «скрипту». Запускается бинарник командой eval и ему передаются все исходные параметры.

Этот Файл c++ нужно скопировать в папку /bin и сделать его исполняемым (chmod a+x).

Попробую написать свой первый «c++ скрипт»:

#!/bin/c++

#include <stdio.h>
#include <iostream>

using namespace std;

int main( int argc, char *argv[] )
{
    cout << "hello world!\n";
    for( int i=0; i<argc; i++)
    {
	cout << "Param" << i <<  " is " << argv[i] << "\n";
    }
    return 60+argc;
}

Эта программа просто печатает список входных параметров и возвращает их количество + 60.
Запускаю мой «скрипт»:



Работает!!!

Если сделать в c++ коде ошибку, то программа не запустится, так как не скомпилируется, но echo $? вернет 255. Но так и задумано было.

Использование c++ дает громадные возможности. Во-первых, привычный синтаксис. Во-вторых, стандартные классы вроде std::vector, std::map или std::string и другие — незаменимые вещи. Та же строка — что хочешь с ней делай, ищи в строке, разбивай на подстроки, разъединяй и властвуй, получай массивы. И не нужны мне ни sed ни awk. В-третьих, отладчик — господи! какое счастье! у меня для скрипта есть отладчик gdb! Дальше, можно использовать std::filesystem (если компилятор позволяет). Можно продолжать…

К сожалению, у меня часто бывает, что сперва сделаю, а потом подумаю: «а вдруг кто-то такое уже сделал?». И в самом деле, я оказывается далеко не первый, кто придумал делать так же. Вот пример: https://github.com/dimgel/cpp-linux-scripts идея та же, реализация другая. Потом оказалось, что есть и другие реализации.

В общем, испытал небольшое разочарование в собственной неисключительности. Однако, поискал по Хабру — похожего не нашел. Может кому-то покажется хотя бы любопытным?

Вы можете помочь и перевести немного средств на развитие сайта

Теги:



Комментарии (71):

  1. CrazyAlex25
    /#21295242

    CERN использует cling (до этого был cint ). Для Си есть tcc с параметром -run

  2. Borikinternet
    /#21295680

    а ещё есть csh, который, с одной стороны, полноценный шел, а с другой — в качестве языка в нем С

  3. iroln
    /#21296092 / +1

    Можно ли писать скрипты на C++

    Конечно можно, но зачем? Мне думается, что правильнее подбирать инструмент под задачу, а не задачу под инструмент. Для скриптинга у C++ слишком многословный и сложный синтаксис, а также относительно бедная стандартная библиотека.


    Для этой задачи гораздо лучше подходит Python и компилировать ничего не надо. Добавить shebang #!/usr/bin/env python3 и запускать прямо из bash. И все возможности stdlib (pathlib, sys, os, shutil, re, argparse, ...) к вашим услугам. А если чего-то не хватает, pip install --user ... и погнали.

    • 0xd34df00d
      /#21300088

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

  4. domix32
    /#21296214 / +1

    вроде std::vector, std::map или std::string т другие
    std::filesystem (если компилятор позволяет)

    конечно забавно скриптовать на C++, но в чем профит — непонятно. Скорости разработки оно не добавляет в сравнении с каким-нибудь питоном, пляски вокруг utf, стандартные контейнеры и filesystem крайне сомнительный профит. Быстрого подключения модулей нет ибо надо прокидывать все это дело компилятору. Предлагаю добавить хаб "ненормальное программирование"

    • nckma
      /#21296268

      Да, возможно это ненормальное программирование. Но насчет скорости, когда bash скрипт запускает из себя множество других процессов типа ls, sed, awk и прочие — а потом ждет их вывода для анализа — это что быстро работает?

      • Borikinternet
        /#21296284

        да :)

        • rPman
          /#21311084 / +1

          Вот буквально только что почитал обсуждение тормозов rm, старейшей утилиты, 'шлифованной десятилетиями'
          <сарказм>

      • arheops
        /#21298790

        Для таких придумали демоны типа speedy, которые второй раз не запускают утилиту.

      • vitvakatu
        /#21299364

        Поверьте, очень быстро

        • iproger
          /#21300006

          Вот все хорошо в консольных утилитах, но до сих пор все они однопоточные. Это во времена когда за 10 лет в процессорах в однопотоке прибавились 30%.
          Не видно даже подвижек чтобы хотя бы пакетные менеджеры использовали много потоков. Хотя бы для распаковки. И так во всем.

          • centralhardware
            /#21300012

            Ест чудная обёртка apt-fast правда она только качает в многопотоке

          • AndreyHenneberg
            /#21300916

            Рискованно производить установку во много потоков — потом можно не несколько дней потратить на восстановление системы. А многопоточная закачка давно есть в том же YUM/DNF.

            А что касается многопоточной работы базовых утилит, не забываем, что работают они с ПОТОКАМИ. То есть каждой скармливается поток, с которым она что-то должна сделать. Если нужно делать что-то в несколько потоков, просто запускаете эти несколько потоков и не маетесь с последовательным запуском. Я так и делаю, причём, во всё том же Bash.

            • iproger
              /#21302640

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

              • AndreyHenneberg
                /#21302700

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

                • iproger
                  /#21302940

                  Можно добавить опцию. Но пока всех устраивает скачивание за 5 минут вместо 1 и распаковку 10 вместо 2.

                  • AndreyHenneberg
                    /#21302972

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

                    P.S. На моей машине и на моей сети закачка идёт в два потока. Хотя и не всегда. Видимо, зависит от загруженности сети и отдающего сервера.

          • rkfg
            /#21302440

            У xargs есть отличный аргумент -P, который как раз и запускает несколько процессов параллельно. Не многопоточность, но загрузить проц до упора вполне можно. Например, для кодирования больших объёмов текста с помощью Sentencepiece или преобразования FB2 ? TXT.

            • AnthonyMikh
              /#21304026 / +1

              Тогда уж можно сразу GNU Parallel вспомнить.

              • rkfg
                /#21305566 / +1

                Можно, но xargs более вероятно будет установлен из коробки. Например, в дебиане он входит в findutils вместе с find (странная группировка, по-моему).

      • domix32
        /#21299510

        это что быстро работает?

        Очень быстро, да. Но эксперимента ради предложил бы переписать утилиту yes из набора coreutils собственными силами и потом помериться в скорости. Там же голые Си под низом, которые отлаживали со второй половины прошлого века. В последней декаде решили еще бустануть, переписав на раст и сделав чуть более человечные API, кроссплатформенность и всякое разное прикольное (см. ripgrep, exa ). Но как упоминалось ниже — речь не про скорость работы, а про скорость разработки. Едва ли с быстренько можно написать какое-нибудь префиксное дерево чтобы вместо grep/sed использовать. Прототипировать может быть удобно, если из консоли не вылазить, но я обычно для такого использую sublime text с настроенной командой для REPL, а то и вовсе использую какой-нибудь wandbox.org или ideone.com. Так что это не та ситуация когда строгая типизация и манипулирование байтами имеет хоть сколько-нибудь значимое преимущество.
        Второй нюанс — это все же не скриптование, а именно перекомпиляция, т.к. для полноценного скриптования нужен интерпретатор, вроде вышеупомянутого cling. Такое скриптование далеко не факт что работает сильно быстрее питона, если вообще быстрее.

        • 0xd34df00d
          /#21300102

          Ну, например, я всякие логи паршу совсем не awk’ом, а работает оно быстрее, выглядит поддерживаемее, да и скрипт пишется быстрее, чем у шарящего в awk коллеги.


          Кстати, как раз завтра выложу статью про борьбу с wc в скорости.

        • AndreyHenneberg
          /#21300996

          Так-то оно, может и так, но прочтите статью внимательнее: автор в Linux ходит что-то вроде раз в месяц и ненадолго. То есть он каждый раз всё гуглит и изучает заново, о чём и написал, кстати. То есть для человека, который в *nix не живёт, но постоянно программирует на C++, это будет серьёзным ускорением работы. Собственно, я сам, используя Linux уже больше 20 лет, так и не осилил разобраться с awk, потому что быстрее построить этажерку из других утилит или перейти на другой язык. Возможно, зря не изучил, но пока нет повода закапываться ещё и в это. sed и тот использую исключительно как обработчик регулярных выражений, хотя знаю, что его возможности гораздо шире. Потому что, если припрёт, к моим услугам Python, на котором я, в основном, и работаю последние 7 лет.

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

          • domix32
            /#21301478

            противопоставление не совсем корректно

            Если называть питон чисто скриптовым языком — да, но я вроде только про скорость выполнения упоминал. Да и компиляция у питона ленивая. Можно было аналогично в противопоставление nodejs упомянуть. Тот еще медленнее да еще и по памяти прожорливее.
            Что до sed/awk — для меня это обычно тоже темный лес. Т.к."сварщик я не настоящий" ибо пишу не с под vim в терминале и руки на мышку перекладываю иногда для моих нужд хватает find+grep с парой заученых ключей. Ну, и питон конечно же.

            • AndreyHenneberg
              /#21302738

              Не уверен, что сейчас ещё остались чисто скриптовые интерпретаторы, потому что проще «день потерять, зато потом за пять минут долететь». Особенно, если сохранять результат компиляции. Разница лишь в том, что питон начинает выполнение сразу, по ходу компиляции, а в варианте C++ надо сначала скомпилировать всю программу целиком.

              • domix32
                /#21304620

                скриптовые интерпретаторы

                ванильный луа, насколько мне известно, не компилируется как питон с артефактами (про новое издание не знаю наверняка). У перла и js/nodejs вроде та же история. Многие лиспы. Преобразование в байткод своей внутренней виртуальной машины не считаю.


                день потерять, зато потом за пять минут долететь

                в такой ситуации обычно имеет смысл завести cmake файл или еще какой-нибудь конфиг сборки, чтобы и в IDE можно было в случае чего кнопкой завести.

              • gecube
                /#21304930

                Разница в том, что питоноскрипт нормально кэширует сборку, а вот поделка автора статьи — кладет исполняемый файл в /tmp, что, конечно, при следующем запуске скрипта приведет к повторной компиляции. А как только автор втащит boost в свой "скрипт" на С++, то "привет, сосед!"


                Чтобы сделать компиляцию безопасной там еще кучу вещей надо сделать — писать sha исходного файла программы, обеспечить конкурентность запуска "скрипта" (что будет если мы один "скрипт" очень быстро запустим два раза подряд), обеспечить пересборку бинаря при изменении кода скрипта и прочее-прочее. И, да, проверка по меткам времени — зашквар. Странно, что это все не продумано

    • yomayo
      /#21299600 / +1

      но в чем профит — непонятно.
      Профит в повторном использовании кода книг Кернигана, Ритчи, Страуструпа & etc.

  5. kuza2000
    /#21296720

    Уважаемый автор! С++ замечательный язык, один из моих любимых. Но… для каждой задачи надо использовать подходящий инструмент. Допустим, вам нужно обработать какой-то лог файл размером NN гигабайт, вытащить оттуда значения, сделать с ними какие-то несложные манипуляции, типа расчета средних, максимальных значений, вывода с сортировкой. Тот, кто владеет perl, grep, awk, sort и регулярками может написать и отладить такой скрипт минут за 15-20. Все эти утилиты внутри очень оптимизированны, начиная от буферного чтения, и заканчивая многопоточностью, если это необходимо. Мало того, они будут соединены в пайп, и работать одновременно, прокачивая через себя данные. То есть, многопоточность будет не только внутри них, но даже на уровне скрипта. Это скрипт легко может загрузить (эффективно!) все 8, или больше, сколько там у вас, ядер процессора.

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

    Так что вот вам мой совет. Начните с малого. Освойте, для начала, например, однострочники на perl и обязательно регулярки. Тут, на хабре, были статьи по обоим темам. С перлом даже awk не понадобиться. grep, sort — там всего-то надо знать по паре-тройке ключей у каждого. Ну а если нужно написать код по сложнее, можно взять, например, питон. После опыта на C++ на нем можно начать писать уже через час после знакомства. Можно и perl, но у него все-же довольно инопланетный синтаксис покажется после C++. Поэтому мой выбор — питон. Но это уже на любителя.

    • nckma
      /#21296756 / -1

      Во многом согласен, только с регулярками не могу согласиться…

      Some people, when confronted with a problem, think
      “I know, I'll use regular expressions.” Now they have two problems.

      • kuza2000
        /#21299384

        Зря вы так про регулярки :)
        Я тоже жил и программировал без них лет 20. Когда встречался с ними — они мне казались то китайским языком, то абракадаброй, то магией. Конечно, я заглядывал в документацию, суть примерно была понятна, но… мозг просто отказывался их воспринимать. Просто не понимал, как такое можно использовать.
        И все-таки не так давно я начал их понимать, использовать и очень этому рад. После некоторой привычки и практики они становятся понятными, и начинаешь ценить всю их мощь. То, что другими средствами выливается в десятки строк запутанного кода, можно записать регуляркой размером в полстрочки.
        А что касается проблем… ну так на любом языке можно писать плохой код. Не надо писать стоэтажные регулярки, и тогда они будут простыми, понятными и надежными. Это — всего лишь инструмент. Причем очень эффективный инструмент, если применять его правильно и по назначению.
        Сейчас, даже если я буду писать на том же C++, и увижу задачу, для которой хорошо подходят регулярные выражения — я буду использовать их и на C++.

        • domix32
          /#21299568 / +1

          На самом деле проблем становится не две, а три+. Если не долбить ими что-то небольшое, то нормально, а если начинать заниматься каким-то массовым процессингом — молиться, чтобы движок регулярок был не слизан с перлового PCRE.

          • Tangeman
            /#21299726

            PCRE не слизан с перлового RE, это просто Perl Compatible RE, движок там совершенно другой, к перлу не имеющий никакого отношения (там только фичи и синтаксис общие) и, честно говоря, даже очень быстрый, особенно с учётом JIT.

            Если вы читали приведённую ссылку, проблема была не в самом движке, а в

            ...poorly written regular expression that ended up creating excessive backtracking.

            Разумеется, PCRE не даёт гарантий времени выполнения, но всё же чаще всего основной источник проблем — это сами выражения, который пишут «в лоб».

            Некоторые другие движки могут давать гарантии и в чём-то могут быть быстрее, но не бесплатно — далеко не всё можно описать в растовском движке или re2 одним выражением или одним его выполнением.

            • domix32
              /#21299926

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

        • toxicdream
          /#21300810

          Желательно чтобы код был не только быстронаписываемым, но еще легкопрочитываемым.
          У регулярных выражении длиннее 15 символов проблемы как с первым, так и со вторым.

          • AndreyHenneberg
            /#21301078

            Эм… Вот тут Вы напомнили мне то, с чего я начинал работу в одной конторе: посадили переписывать генератор интерфейса RPC с Java на C#. То есть был генератор, который парсил документацию под интерфейсу и собирал код на Java, а надо было сделать такой же, но чтобы код был на C#. Он тогда только появился, так что wow-эффект у заказчиков только начинался и они страстно хотели именно C#. В общем, посмотрел я на чудовищные регулярки и отсторожно отошёл в сторонку. Потому что они там были за сотню символов длиной. И просто скопировал их в итоговый продукт, меняя только ту часть, которая склеивала код. Написано было, кстати, на Perl, из-за которого меня, новичка в конторе, и посадили за эту работу.

            • toxicdream
              /#21303142 / +1

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

    • VioletGiraffe
      /#21298150 / +2

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

    • rboots
      /#21298328

      Все эти утилиты внутри очень оптимизированны

      По поводу оптимизации некоторых системных утилит, когда смотришь что они делают через strace — страшно становится. Взять хотя бы канонический пример, утилиту /bin/true, занимающую 25 килобайт! Да, я знаю, туда зашит слой совместимости для разных случаев, а так же хелп, но не нужно говорить, что он будет работать быстрее, чем самописный, оптимизированный для частного случая. Вообще, почти весь софт последних 50 лет был вдохновлён законом Мура и работает быстро только потому, что написан давно (под старые слабые процессоры) и делает довольно простые вещи, но то, что какая-то утилита выполняется за 0.5 миллисекунды не значит, что она быстрая, если тоже самое можно сделать за 0.05. Какое это имеет практическое значение? С точки зрения «мне нужно закрыть этот тикет к четвергу» — никакого. Но с точки зрения базовых кирпичиков, из которых строится фундамент, на котором будет стоять огромный небоскрёб кода — это имеет значение, потому что если фундамент гнилой — всё будет медленно и ресурсозатратно, что мы и видим почти во всех современных решениях. Одна утилита выполняет простое действие за 1мс вместо 0.01мс, она используется 50 раз в другой утилите, а та 50 раз в третей, которую вы вызываете из командной строки, в итоге вы имеете 2.5 секунды на отработку скрипта вместо возможных 25 миллисекунд. Собираясь вместе, например в сборке CI, такие утилиты набирают несколько минут, а то и часов, и мы идём пить кофе пока «оно компилируется». Из за того, что что-то занимает 25 килобайт, вместо 8кб при наивной реализации без лишнего функционала или 1кб при удалении clib и прочих неиспользуемых библиотек. Я не говорю про квадратичный рост вычислений, который тоже иногда проскальзывает, почитайте хотя бы что Джоэл пишет про zero terminated strings. Раньше тоже думал, что систему пишут очень умные ребята и у них всё оптимизировано. Они правда очень умные, но во многих местах улучшать не переулучшать, просто никто туда не лезет.

      • gecube
        /#21304942 / -1

        Все так, но время и качество разработки тоже учтите! Вот все эти утилиты полировались годами и десятилетиями и вероятность критичных багов в них… стремится к нулю. А вот Ваша персональная имплементация "yes" — с какой попытки Вы ее корректно напишете, учтете все corner-case? Т.е. — несомненно — нужно работу вести в обоих направлениях — и решать более сложные задачи на базе уже существующего фундамента в виде команд, платформ и фреймворков, а также заниматься написанием нового, но с умом, если это оправдано в конкретном случае. А не просто чтоб было. Примеров неудачных программ, созданных только из NIH — масса

  6. PyerK
    /#21297308

    Отличная идея. Ещё если ccache добавить, вообще супер будет.

  7. Tangeman
    /#21297824

    Во-первых, привычный синтаксис.

    Это пока вам не нужно часто делать что-то вроде
    app | filter1 | filter2 | filter3
    или даже банальном
    app1 || app2 && app3
    замучаетесь с этим на «чистом» C++, да и многословнее гораздо — нечто простое вроде
    for x in $(find . -type f); do app $x; done
    будет очень ветвисто.

    • dvrpd
      /#21298846

      А зачем конкретно в этом примере for x in $(find. -type f), если у find (по крайней мере, в GNU coreutils) есть параметр -exec?

      • Tangeman
        /#21299696

        Чисто для иллюстрации итерации по результатам вывода процесса. Но если это кажется слишком простым — ок, усложним:

        for pid in $(ps axuh|awk '{if ($6 > 3000 && $2 > 1) print $2}'); do
          kill $pid
        done
        

        • 0xd34df00d
          /#21303592

          Вы наизусть помните, в какой колонке ps axuh что лежит?

          • kprohorow
            /#21303606

            Помнить не обязательно, есть man.

            • 0xd34df00d
              /#21304650 / -2

              Документация на код, которую мы заслужили.

          • Tangeman
            /#21305114

            Как уже выше ответили — есть man, но когда мне нужно «вот прям щаз» и что-то не вспоминается — я 15 секунд изучаю вывод «ps axu», смотрю колонки, и ещё 45 секунд пишу этот скрипт.

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

            • 0xd34df00d
              /#21305128 / +1

              А когда вы читаете чужой скрипт?


              Обычно когда пишут какую-нибудь программу, работающую с каким-то форматом данных, поля в соответствующей структуре данных не называют как как f0, f1, f2, а стараются дать им более осмысленные имена, хотя документация на формат рядом. Как думаете, почему?

              • Tangeman
                /#21308706 / +1

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

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

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

      • arheops
        /#21299938

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

        • iig
          /#21301148

          В этом случае я xargs использую. +1 к понятности.

    • mayorovp
      /#21300522

      Ну, если базовые "кирпичики" реализует кто-то другой — то все три примера можно будет перенести в C++ чуть ли не 1 в 1. А ваш 4й пример так даже проще получится.

  8. DerRotBaron
    /#21298466

    Не говоря про то, что значительная часть скриптовых задач не решается на C++ без тонны кода на C или сторонних либ вроде boost, в этой статье сразу 3 пути по отстрелу ног в современном Linux.
    Во-первых свои утилиты без пакетного менеджера класть в /bin довольно плохая идея, т.к. это может привести к конфликтам при обновлении релиза ОС и не только.
    Во-вторых скрипт довольно очевидно небезопасный, поэтому выпускать его куда-либо дальше личной однопользовательской машины в таком виде не кажется хорошей идеей.
    Ну и наконец на современных ОС в таком виде это в принципе будет нарушать работу ОС:
    /usr/bin/c++ исторически принадлежит компилятору c++ (напрямую или через alternatives, зависит от системы). В последнее время /bin — симлинк на /usr/bin, соответственно в этом случае либо сломается скрипт (g++ не сможет его запустить), либо сломается сборка плюсов в сборочных системах, которые по умолчанию вызывают c++ из PATH

  9. NeoCode
    /#21298994

    Насколько я знаю, такая встроенная возможность (с shebang в первой строчке) есть в языке D.

  10. Neveil
    /#21299152

    Знаю точно, что завтра многое забуду и через месяц опять буду гуглить

    Я веду личную базу знаний для всего, что гуглится дольше 15 мин.

    • centralhardware
      /#21300276

      С помощью какого ПО? если удобно и для себя начну вести

      • Neveil
        /#21301230

        С помощью приватного репозитория в github.

  11. MaxVetrov
    /#21299170

    Можно убрать:

    #include <stdio.h>

    • EvilMonk
      /#21301436

      +1. Тоже не понял, зачем здесь stdio.h

  12. kovserg
    /#21299544

    Живо представил как подключаешь к такому скрипту boost и………
    image

  13. sim2q
    /#21300118

    В общем, испытал небольшое разочарование в собственной неисключительности.
    Хмм… а я наоборот если вижу, что так уже кто-то сделал, думаю, что не так уж и туп раз пошёл по пути по которому уже кто-то сделал и работает :)

  14. Newbilius
    /#21300468

    Может стоит добавить в хабы "ненормальное программирование?" Тогда всё встанет на свои места :)

  15. MisterN
    /#21301160

    Проблема еще оказывается в том, что зачастую не пишешь скрипт заново, а модифицируешь существующий, уже написанный кем-то. А он может быть не bash, а sh или еще что-то… Различия в синтаксисе есть, что работает в sh по идее должно работать и в bash, но не всегда наоборот. А если там dash или ash?

    Отомстим им всем — запилим скрипт на плюсах, пусть удивляютцо ))) Шутю-шутю.
    Вы жалуетесь на сложности с различными оболочками в скриптах, написанных различными другими людьми и как решение предлагаете нестандартный, но хорошо знакомый язык. А как оно решает проблему дебага уже готовых скриптов? Переписыванием их с нуля?

  16. kprohorow
    /#21302014

    "— Всё это истинно. Тем не менее, в одной строчке баш-скрипта всё равно больше духа Unix, чем в десяти тысячах строк кода Си."
    © Master Foo and the Ten Thousand Lines

  17. MaM
    /#21302446

    Раз уж пошел такой разговор на Rust тоже можно github.com/DanielKeep/cargo-script, а еще вроде как идет разработка github.com/PistonDevelopers/dyon.