Huawei 1550 + Asterisk = дешевый GSM шлюз

Huawei 1550

Что мы имеем:
3g модем на базе Huawei 1550 разлоченый под все, что только можно (MMC+ голос + видео+ любой оператор …) и
– сервер на базе Gentoo x64, kernel 2.6.38
Asterisk 1.8.4.1



Для корректной работы модема требуется ядро выше 2.6.33. В моем случае запаса хватает
В самом ядре необходимо отметить такие пункты

Device Drivers ->
    USB support  --->
        <*> OHCI HCD support
        <*> USB Serial Converter support  --->
            [*] USB Generic Serial Driver
            <*> USB driver for GSM and CDMA modems

Continue reading

Как защититься от платных подписок в Билайн

Вот такое обнаружил, когда зашел в личный кабинет. Билайн втихую подключил платные подписки. Позвонил им, поругался. Вернули 600р (накапало за время, пока было подключение услуг) без лишних разговоров.

Чтобы не подписывалось далее порекомендовали:
Подключить этот отдельный счет для платных сервисов (не пополняемый автоматически) можно по ussd-запросу *110*5062# (отключить *110*5060#).

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

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

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

Эргодичность – 300 лет в искаженной реальности

эргодичность

Назрел крупнейший прорыв в понимании случайности

Этот рисунок изображает параллельные миры, разветвляющиеся в будущее, когда реальность выбирает одну траекторию в пространстве возможностей. AMERICAN INSTITUTE OF PHYSICS. Credit: Peters and Gell-Mann

 

Этот рисунок изображает параллельные миры, разветвляющиеся в будущее, когда реальность выбирает одну траекторию в пространстве возможностей. AMERICAN INSTITUTE OF PHYSICS. Credit: Peters and Gell-Mann

Представьте себе совершенно дикий по идиотизму пример.

  • Допустим, что в наше время общепринятым представлением о мироустройстве является геоцентрическая система: центральное положение во Вселенной занимает неподвижная Земля, вокруг которой вращаются Солнце, Луна, планеты и звёзды. И этим представлениям о мироустройстве уже 300 лет.
  • Но 10 лет назад была сформулирована альтернативная — гелиоцентрическая гипотеза: будто Земля и другие планеты вращаются вокруг Солнца.
  • А в 2016 году двумя известными физиками (один из них Нобелевский лауреат, совершивший переворот в физическом представлении о мире) была опубликована статья, в которой гелиоцентрическая гипотеза доведена до уровня физической теории (эта статья стала самой читаемой научной публикацией года в журнале).
  • И совсем недавно — в июле сего года вышло экспериментальное психологическое исследование, показывающее, что вшитые в человека от рождения нейробиохимические механизмы (биоритмы и т.д.), как бы настроены на то, что Земля вращается.

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

Согласитесь, — пример действительно дурацкий.

Разве подобное возможно?

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

И вот в начале декабря случилась сенсация.

Авторитетный научный журнал Nature Physics публикует статью «The ergodicity problem in economics». Ее автор Оле Питерс — продолжает тему, начатую в знаменитой статье 2016 года «Evaluating gambles using dynamics», написанной совместно с нобелевским лауреатом великим Мюрреем Гелл-Манном (тот, к сожалению, уже умер).

В новой статье утверждается, типа, —

«И все-таки она вертится!».

В смысле, что пора науке решиться и поменять-таки представления о вероятности. Потому что, если коротко, ситуация такова.

  • Многие современные науки основаны на искаженном представлении о реальности. Это искажение является следствием сложившихся около 300 лет назад ошибочных представлений о вероятности (риска, удачи, счастья …).
  • Лежащее в основе этих представлений формальное понимание математики случайности 300 лет назад было в зачаточном состоянии и концептуально наивно. Предполагалось:
    – что случайность, возникающая в единственно существующем пространстве с необратимым временем, имеет тот же эффект,
    – что и случайность, возникающая в ансамбле параллельных вероятностных миров.
  • В 18 веке экономика (первая дисциплина, веком раньше разработавшая математику случайности ) заметила нестыковки теории и практики, возникающие из-за подмены временной вероятности на ансамблевую, и разработала инструменты (типа теории полезности), хоть как-то смягчающие некоторые из нестыковок. Там же, где наблюдалось резкое отклонение поведения людей от предсказаний экономических моделей, просто было объявлено, что это следствие иррациональности человеческой психики.
  • В 19 веке в физике, а именно в термодинамике и статистической механике, была разработана новая концептуализация случайности. Эта концептуализация с самого начала признавала центральную роль времени в случайных процессах. Тем самым в физике был устранен фундаментальный недостаток — путаница в применении временной и ансамблевой вероятностей.
  • В экономике же и прочих неточных дисциплинах, изучающих принятие людьми решений в условиях неопределенности (финансы, социология, психология и т.д.), все пока что остается, как и 300 лет назад.

В результате этого человечество имеет массу проблем:

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

Чтобы исправить все это, необходима смена человечеством модели рациональности. А это влечет за собой будет весьма серьезные последствия:

— полный пересмотр экономической теории и практики финансовых спекуляций;

— кардинальное изменение трактовки причин нарастающего неравенства;

— принципиальная смена подходов в практике прогнозирования и принятия решений;

— отказ от использования многих привычных показателей и индикаторов (типа понятия ВВП в качестве индикатора уровня процветания);

— демонтаж и замена существующих систем страхования и пенсионной системы

… и много чего еще.

✔️ Так что ж, если такая научная трактовка прошла рецензирование и опубликована в Nature Physics, — мы на пороге новой научной революции?

Полагаю, что это весьма возможно. Но решать не мне.

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

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

Из прошлого в будущее много путей, но реализуется лишь один

«Учитывая ход времени, ваша способность играть в игру завтра зависит от последствий сегодняшних решений».
Оле Питерс

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

Игра такова.

  • У меня $100 (это мой начальный баланс).
  • Я подбрасываю монету (она симметричная и бросаю ее без жульничества).
  • Если выпадает орел, я выигрываю 50% от моего текущего баланса.
  • Если выпадает решка, я теряю 40% текущего баланса.

Таким образом, если после 1го броска монеты выпадет орел, я выигрываю $50, а если решка, то потеряю $40.

 

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

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

Напомню.

Ожидаемое значение случайной величины (в нашем примере, очередной орел или решка) подсчитывается по формуле математического ожидания:

Е(х) = p1*х1 + p2*х2 + … + pn*xn

где р1, р2, … pn — вероятности каждого исхода, х1, х2, … xn — значения каждого исхода: либо прибавка 50% к текущему балансу, либо его сокращение на 40%.

Тогда, математическое ожидание денежного выигрыша после первого броска монеты, составляет (0,5*$ 50 + 0,5*$ — 40) = $5 или 5% прироста текущего баланса. Рассуждая дальше, матожидание денежного выигрыша после второго броска монеты составляет (0,5*52,5 + 0,5*$ -42) = $5,25. Еще 5% прироста текущего баланса.

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

Теперь начинаю играть.

Желающие могут далее

  • либо смотреть видео, на котором Оле Питерс рассказывает (по англ.) о ходе игры и обнаруживаемых поразительных сюрпризах;
  • либо читать далее эту главу, где поясняющих картинок будет даже больше, чем в рассказе Оле.

Игра в миллионе параллельных реальностей

Бросаю 5 мин (по 1 броску в минуту). Получилось вот что. Красная линия показывает состояние текущего баланса после броска. Первые 2 раза была решка, потом орел, снова решка и опять орел.

 

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

Играю дальше еще 55 мин (все так же, по броску в минуту). Получилась 60-минутная серия бросков.

 

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

 

Кто-нибудь видит здесь хоть какой-то тренд? Я не вижу. Значит все еще мало бросали. Делаю еще 10 серий. Итого получаю 20 серий бросков по 60 раз.

 

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

 

Тренда пока не просматривается. Но я не сдаюсь. Делаю 1 тыс. серий и вычисляю для каждой минуты средние значения…

Тру-ту-ту-ту! Приз в студию! Вот что получилось.

 

Чем ни тренд? Жаль только в конце график почему-то вниз повалился. Надо еще больше серий сделать.

Делаю 1 миллион серий. И каков результат — загляденье!

 

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

Но постойте. Надеюсь вы понимаете, что на самом деле,

я не бросал монету 114 лет, чтобы сделать 1 млн. серий по 60 бросков в час.

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

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

✔️Но что означает тот факт, что полученное мною итоговое усреднение было сделано для 1 млн. траекторий?

  • Я как бы набрал 999999 студентов и одновременно с ними сделал 1 млн. серий, каждая из которых включала 60 попыток по одной в минуту?

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

Но нет у меня никаких параллельных реальностей.

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

Нет, это какой-то бред. Надо уходить от параллельных реальностей.

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

Игра в единственной существующей реальности

Начну, как и раньше, сделав 60 бросков.

 

Потом просто стану бросать дальше в течение суток.

 

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

Продолжаю играть все ту же единственную игру. Но черт побери! Я все больше и больше проигрываю. Начальные 100 баксов быстро растаяли до малых долей цента. Попробую играть целую неделю. Вдруг начнет везти.

 

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

 

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

✔️В чем же дело? Почему получились две несравнимо разные картины?

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

Получается, как будто:

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

— но если кто-то один достаточно долго играет в эту игру (временной вариант), он теряет почти все свои деньги.

Какой-то бред сумасшедшего получился!

Может ошибка какая вкралась?

Надо проверить оба варианта на симуляторе.

Проверка ансамблевого варианта

Желающие могут сами это сделать, воспользовавшись анимированным симулятором игры, запрограммированным Сидом Шанкером (правила в этой игре чуть-чуть численно отличаются: за орла и решку выдается не +50% и -40%, а +55% и -45%, но это принципиально ничего не меняет).

В ансамблевом варианте в игру играют 40 человек, и каждый бросает монету 20 раз. Начальный баланс у всех одинаковый — $100.

Вот перед вами итоги 4х игр (вы сами можете сгенерировать еще хоть 1000 подобных игр на симуляторе).

 

На вышеприведенной картинке показано для каждой из 4х игр:

  • траектории выигрыша двадцатки (больше на анимированном графике не умещается) наиболее успешных (по размеру итогового выигрыша) игроков;
  • сумма итогового выигрыша этой же «великолепной двадцатки» после последнего 20го броска (на анимированном графике симулятора, перемещая курсор, можно смотреть также все промежуточные результаты после каждого броска);
  • среднее значение итоговых выигрышей всех 40 игроков.

Что особенно интересно.

— Среднее значение выигрыша для всех игроков в конце игры (указано сверху слева), как правило, выше $100 (оно и понятно, игра же выгодная).

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

Например, в 1й (самой «несправедливой») игре, средний итог игры составил аж $754, но это большущее среднее получилось так:

  • игрок №23 огреб $28+ тыс.,
  • а игроки №№39, 37, 34, 32 (а также игроки 2й («омерзительной») двадцатки, продули почти все, имея к концу игры лишь по $7.

А в самой «справедливой» 3й игре, средний итог игры составил $118, а это скромное среднее получилось из такого разброса:

  • игроки №№35 и 13 огребли по $1279,
  • а игроки №№37, 34, 32, а также №№28, 22, 21, 18 остались после игры всего с парой десятков баксов (а игроки «омерзительной» двадцатки еще с меньшими суммами).

Возникает резонный вопрос.

✔️С кем из игроков я должен себя ассоциировать при принятии мною решения?

И вообще:

— выгодная это игра или нет?
— стоит ли мне в нее играть?

Мне равняться на результат игрока №23, что огреб $28+ тыс. в 1й игре?

Или на его же результаты в играх с 2й по 4ю, где он сильно продул, не выйдя из «омерзительной» двадцатки?

Ведь ориентироваться на среднее между всеми игроками нет смысла: я же один буду играть и всего один раз, сделав 20 бросков монеты.

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

Проверка временного варианта

В этом варианте симулятора вы просто жмете на «Play» (на статичном рисунке ниже это клавиша в состоянии «Сброс»/«Reset», т.к. это скриншоты с анимации) и игра идет до бесконечности, совершая все новые и новые случайные броски монеты и, соответственно, увеличивая или уменьшая текущий баланс игрока.

Вот пример одной игры.

 

На верхнем графике показана траектория текущего баланса игрока до 65го броска монеты. Как видите, 35 бросков сказочно везло, что позволило на 33м броске довести выигрыш до $2 тыс. Но потом везение кончилось, и к 65у броску баланс устремился к нулю.

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

Вот 4 из них в качестве примера. Игры довольно длинные (количество бросков монеты: 158, 175, 652 и 872), чтобы не вкралось сомнение, будто их плачевный исход — плод недостаточно длинных серий бросков.

 

Увы. Исход у меня получился всегда один и тот же.

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

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

Вывод

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

В 2х вариантах этой игры получаются кардинально разные результаты.

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

✔️А когда один человек играет в игру много раз, происходит усреднение по времени, и ожидаемый выигрыш отрицательный (то есть неотвратимый проигрыш).

 

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

✔️ Но как же такое может получаться — игра одна, а результаты разные?

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

Эргодичность

«Нет вероятности без эргодичности»
Нассим Талеб

Мы привыкли, что вероятность, применимая к группе людей (ансамблевая вероятность) и вероятность, применимая к одному человеку (временная) совпадают.

Если вы бросите игральную кость 100 раз, сколько раз выпадет шестерка? Нет сомнений, что где-то в районе 17 раз.

А если попросить 100 человек по разу бросить кость, то сколько шестерок в сумме у них выпадет? И опять нет сомнений, — тоже примерно 17.

Т.е. получается, что в примере с игральной костью среднее по времени и среднее по ансамблю получаются одинаковые, а в примере из предыдущего раздела поста — с бросанием монеты и +50%ным или -40%ным изменением баланса — они разные.

Объяснение этому отличию было предложено еще в 1884 великим австрийским физиком-теоретиком, основателем статистической механики и молекулярно-кинетической теории Людвигом Больцманом.

Он ввел новое понятие — эргодичность для процессов, в которых среднее по ансамблю и среднее по времени совпадают.

Такие процессы были названы эргодическими. Соответственно, процессы, в которых эти 2 средних не совпадают, были названы неэргодическими.

Это слово, являющееся определением важнейшего класса случайных процессов, столь редко в использовании, что Google на запрос «неэргодический» дает всего около 600 ссылок (для сравнения, на запрос «вероятность» выдается 63+ млн. ссылок — в 100 тыс. раз больше). И это соотношение таково, поскольку, на самом деле, лишь 1 человек из примерно 100 тыс. слышал, что бывают неэргодические случайные процессы. А их в реальной жизни пруд пруди, т.к.

сама жизнь по своей природе неэргодична,

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

Если мы, оценивая рискованность (привлекательность) какого-то своего действия (напр. инвестиции или ставки в игре случая), не заморачиваемся с вопросом эргодичности, это грозит нам печальным результатом. Как было показано в предыдущем разделе,

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

Напомню уже известный вам рисунок.

 

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

✔️ Но в чем же коренится столь коварная иллюзия?

✔️ Что заставляет человека столь кардинально лопухнуться с оценкой перспектив, приняв неэргодический процесс за эргодический?

Причин, по большому счету, две.

Первая, — замена временной вероятности на ансамблевую.

В этой простодушной замене при оценке ожидаемой выгоды, среднее по времени просто заменяется на среднее по ансамблю. Это ловкий трюк, многим кажется чрезвычайно полезным, так как ансамбль средних значений, как правило, значительно проще и, главное, гораздо быстрее вычислять по сравнению со средним по времени. Ждать, когда последовательно произойдет множество событий, долго. А как говорил О.Бендер, — время, которое у нас есть, — это деньги, которых у нас нет.

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

Другая причина — наличие в жизни необратимых последствий.

В результате этого,

для неэргодических процессов наблюдаемая в прошлом вероятность не применима к будущим процессам.

Нассим Талеб называет такие необратимые последствия «гибелью» — попаданием в экстремально поганую ситуацию, не подразумевающую восстановление.

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

Предположим, что шестеро людей играет в русскую рулетку: каждому по выстрелу и приз в $1 млн. долларов.

 

После шести выстрелов, скорее всего, пять из шести играющих останутся в выигрыше. Если использовать стандартный анализ выгоды и затрат, можно утверждать, что вероятность выигрыша у каждого из игроков составляет 83,33%, а «ожидаемый» средний доход в результате каждого выстрела составит около $833333. Но проблема в том, что при многократной игре в русскую рулетку (более одного прохода по всем стреляющим) кто-то непременно попадет на кладбище. И поэтому, ожидаемый доход… просто не вычисляем.

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

 

На рисунке показана разница между ситуациями, когда:

  • 100 человек идут вечерком развлечься в казино, и кому-то, возможно, не повезет (верхний рисунок);
  • один человек ходит в казино каждый день в течение 100 дней.

В первом варианте нет никакой зависимости от каких-либо событий в прошлом. И потому привычное понимание вероятности (ансамблевой) здесь вполне применимо. А если кто-то из 100 пришедших проигрывает все, что имел, — это, при расчете средних значений, как бы происходит в одном из «виртуальных вероятностных миров», а во всех остальных «мирах» (где как бы играют другие 99 игроков) все нормально.

Второй вариант совсем иной. В нем вероятность зависит от прошлого. Идя в казино сотый раз человек имеет за плечами 99 предыдущих игровых вечеров. Поэтому:

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

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

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

А в наши дни это неразличение разных вероятностей при анализе больших данных (основанном на вероятности больших ансамблей) грозит еще большим масштабом заблуждений и ошибочных решений при:

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

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

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

 

Как видно из рисунка, за обе перспективы (ансамблевую и временную) топили многие великие умы.

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

Рассмотрим чуть подробней конкретные последствия подобных ошибок.

Цена искаженной реальности

«Экономика так и не состоялась, как наука, поскольку мы должным образом так и не определились с ее основанием. Если в экономике никогда не было Галилея, как же здесь могут появиться Ньютон или Эйнштейн?»
Джеффри Уэст

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

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

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

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

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

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

Так почему же это не делается?

Прямолинейный Нассим Талеб винит тупость и упертость экономистов. Более политкорректные специалисты объясняют это мотивацией ключевых акторов, заинтересованных, чтобы ситуация не менялась.

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

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

Ведь как я уже писал выше.

Жизнь, сама по себе, неэргодична.

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

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

В этом году было доказано

люди интуитивно различают эргодические процессы от неэргодических.

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

 

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

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

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

✔️ Так чем тогда экономика отличается от религии, если оказывает большее уважение к авторитету, чем к реальности?

Великий Л.Д.Ландау писал, что

науки делятся на естественные, неестественные и противоестественные.

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

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

Ведь это возможно. Единственное, что требуется, как пишет в декабрьской редакционной статье журнал Nature Physics, — выйти за рамки привычного «среднего мышления». И, похоже, что время для этого пришло: Time to move beyond average thinking.

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

Credit: Pasquale Cirillo

 

Credit: Pasquale Cirillo

________________________________

Запуск программы в скрытом режиме в ХР

Бывают ситуации, когда надо запустить на компьютере пользователя программу в скрытом виде (чтобы не было кнопки программы на панели задач и иконки в трее, а также чтобы не было видно окна программы), однако программистами в программе не предусмотрен такой режим запуска.
Например, запуск какого-то монитора работы пользователя или клавиатурного шпиона… В этом случае можно воспользоваться средствами WSH для скрытого запуска таких программ. Вот пример JS-скрипта, запускающего в таком режиме обычный виндовый блокнот:

var WSHShell = WScript.CreateObject(“WScript.Shell”);
WSHShell.Run(“notepad”,0);

Второй параметр во второй строке, а именно – 0, указывает, что надо запустить файл в невидимом режиме. Создайте файл с расширением *.js и пропишите его в автозагрузку. Теперь работа твоей программы практически незаметна. Окно у нее невидимо, кнопки на панели задач нет, в диспетчере задач на вкладке “Приложения” она тоже не светится. Только в списке процессов возможно найти notepad.exe и снять его. Но если обозвать запускаемый файл позаковыристей, например, nvidia32.exe или volsnd32.exe, то далеко не каждый юзер найдет эту подделку. Да и потом, часто ли вы лазите в диспетчер задач с целью поиска “непонятных” процессов?

Тонкости работы в командной строке Windows

Недавно я вырос из лютого эникея в очень большой компании, до скромного сисадмина надзирающего за сетью в 10 ПК. И, как очень ленивый сисадмин, столкнулся с задачами по автоматизации своей деятельности. Полгода назад я еще не знал, что в командной строке Windows есть конвейеры. Это стало первым шокирующим открытием. И я пошел дальше, и выяснилось, что там, где я раньше писал утилитки на C#, Delphi или громоздкие скрипты с вложенными циклами, можно было обойтись парой команд forfiles или robocopy.
Не буду рассказывать о банальностях, типа о перечислении файлов и папок клавишей Tab. Под хабракатом расскажу о том, что может быть полезно начинающим админам и эникеям.

Горячие клавиши

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

F1 — В консоли эта клавиша работает в точности как и стрелка вправо, т.е. выводит по одному символу из последней введенной (либо выбранной в истории) команды.
F2 + <символ> — Выводит последнюю введенную команду до указанного символа. Например, если последняя введенная вами команда выглядела вот так:

ping 192.168.25.1

то после нажатия комбинации клавиш F2 + 5 вы получите:

ping 192.168.2

F3 — Выводит последнюю, и только последнюю, в истории команду целиком.
F5 — Выводит последние введенные команды по порядку, также как и стрелка вверх.
F6 — Вставляет символ EOF на текущую позицию командной строки, что аналогично нажатию комбинации Ctrl + Z.
F7 — Диалоговое окно, содержащее историю команд.
image
Alt + F7 — Очищает историю команд.
<символ(ы)> + F8 — Перебирает команды, которые начинаются с символов уже введенных в командную строку.
Если перед нажатием F8 ничего не вводить, то эта клавиша будет работать как и стрелка вверх, но с небольшим отличием — перебор строк будет осуществляться циклично, т.е. после первой команды из списка будет выведена последняя.
F9 + <число> — Вставляет команду из истории под соответствующим номером. К примеру, в ситуации приведенной на скрине выше при нажатии комбинации F9 + 4 в консоли появится:

ipconfig

 

Операторы командной строки

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

Оператором конвейера в *nix и cmd, является символ вертикальной черты.

|

Например, вывод всех текстовых файлов в текущей папке покажет команда

dir | find ".txt"

 

Оператор объединения команд

 

&

Пример: Команда1 & Команда2 – сначала выполнятся Команда1, а уже потом Команда2

Оператор И

 

&&

Пример: Команда1 && Команда2 — Команда2 будет выполняться только в том случае, если произошло успешное выполнение Команды1

Оператор ИЛИ

 

||

Пример: Команда1 || Команда2 — Команда2 будет выполняться только в том случае, если Команда1 не смогла выполниться.

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

  • (Команда1 & Команда2) && Команда3 – Если Команды1 и Команды2, выполнятся успешно, произойдет выполнение Команды3.
  • (Команда1 & Команда2) || Команда3 — Если Команды1 и Команды2, не выполнятся, произойдет выполнение Команды3.

Спасибо за внимание! Жду критики и предложений…

UPD1

Для тех, кто не в теме, циркумфлекс(вот этот знак “^”) означает нажатие клавиши с Ctrl(^C = Ctrl +C).

^C — Прерывает команду, ну это все знают.
^S — Приостанавливает выполнение команды, а потом запускает.
^I — Аналог Tab, перебирает папки и файлы.
^M — Аналог Enter.
^H — Аналог Backspace.
^G — Написав в пакетном файле команду echo ^G можно пикать системным динамиком(спикером).
(Команды ^I и ^H, получены мной методом «научного тыка», еще есть ^J но не знаю, что она делает)

P.S. Другие тонкости командной строки Windows, уже неоднократно освещались на Хабре. И не вижу смысла копи-пастить.
P.P.S. Ссылки на интересные посты и статьи по другим возможностям командной строки Windows:
Ввод-вывод, циклы, переменные
Работа с массивами
Интереснейший топик по теме


Примеры:

for /f %%z in ('dir %1 ^| find /i ".rar"') do set idate=%%z
for /f "tokens=1-6 delims=/" %%A in ('echo %idate%/%date%') do set /a t=%%F*1461/4-%%C*1461/4+%%E*1461/48-%%B*1461/48+%%D-%%A
if %t% gtr %2 (del /q %1)

скрипт удаляет архивы в папке %1, старшие %2 дней.

forfiles /P %1 /M *.rar /P C:\Your_Directories /D %2 “cmd /C del /Q @path”

Как экранировать символ?

В командном языке Windows существует некоторый набор символов с высоким приоритетом, которые всегда трактуются как спецсимволы. К ним, в частности, относятся:

  • Операторы перенаправления ввода-вывода <, >, >>.
  • Оператор конвейера |.
  • Операторы объединения команд ||, & и &&.
  • Оператор разыменования переменной %…%.

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

      echo
      The ratio should be up to 10%.

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

      echo
       The ratio should be up to 10%%.

после чего все заработает так, как надо. Однако в других случаях все менее очевидно. Рассмотрим командный сценарий, который генерирует незатейливый HTML-файл:

      @echo
      
      off
      
      set OUTPUTFILE=%1

echo<html>                                  >%OUTPUTFILE%
echo<head>                                 >>%OUTPUTFILE%
echo<title>This is a greeting page</title> >>%OUTPUTFILE%
echo</head>                                >>%OUTPUTFILE%
echo<body>                                 >>%OUTPUTFILE%
echoHello World!                           >>%OUTPUTFILE%
echo</body>                                >>%OUTPUTFILE%
echo</html>                                >>%OUTPUTFILE%

К сожалению, при попытке запуска этого “чуда инженерного разума” нас постигнет неудача в виде сообщения об ошибке

> was unexpected at this time.

Оно и понятно: командный интерпретатор не в силах разобраться, где его просят вывести на экран символ HTML-тега, а где перенаправить вывод. В нормальных языках программирования эта проблема обычно решается обрамлением строковых литералов кавычками. Отчасти это помогает и в bat-файлах. Но лишь отчасти. Выполнение строки

      echo
      "<html>"                                 >%OUTPUTFILE%

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

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

      @echo off
set OUTPUTFILE=%1

echo^<html^>                                    >%OUTPUTFILE%
echo^<head^>                                   >>%OUTPUTFILE%
echo^<title^>This is a greeting page^</title^> >>%OUTPUTFILE%
echo^</head^>                                  >>%OUTPUTFILE%
echo^<body^>                                   >>%OUTPUTFILE%
echoHello World!                               >>%OUTPUTFILE%
echo^</body^>                                  >>%OUTPUTFILE%
echo^</html^>                                  >>%OUTPUTFILE%

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

Как перенести длинную строку?

Совет по поводу экранирующего символа ^ имеет еще одно применение: перенос строк. Я (как и многие из вас, наверное) люблю, чтобы любой исходный текст, который я пишу, выглядел красиво – даже *.bat-файлы. Одним из обязательных условий красоты и удобочитаемости кода для меня является его ширина: все строки должны умещаться в 78 столбцов. Можно поспорить по поводу числа 78, но в одном я непреклонен – ограничение на ширину текста кода должно быть, иначе это не код, а макароны.

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

packagebin.exe --recursive-search=yes --files-mask=exe,dll,pdb,obj ^
    --archive-type=zip --archive-level=max --deliver-method=ftp    ^
    --deliver-target=ftp://ftp.site.com

Помните лишь, что чудо-символ должен быть последним в строке – скажите «Нет!» концевым пробелам.

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

Иногда сценарию надо знать полный путь к себе самому и/или к каталогу, в котором он находится. Это может понадобиться по разным причинам. Например, он должен достать из системы контроля версий исходники в каталог <script-dir>/src рядом с собой. Или, запускаются тесты из каталога <script-dir>/tests, и перед их запуском надо добавить каталог <script-dir>/bin в переменную PATH.

Можно, конечно, рассчитывать на то, что командный файл был вызван из того же каталога, где он находится, и тогда в качестве вышеупомянутого <script-dir> можно использовать переменную окружения %CD% – полный путь к текущему каталогу. Однако любые допущения в нашем деле недопустимы (хороший каламбур, однако!). Поэтому приведу более надежное решение.

Прежде всего, вспоминаем, что переменная %0 в bat-файле соответствует нулевому аргументу командной строки, т.е. имени самого файла. После этого читаем скудную документацию для команды call:

      call /?

и обнаруживаем, что при использовании нумерованных переменных %0-%9 можно использовать некоторые модификаторы:

        %~1         - разворачивает %1, удаляя кавычки (")
        %~f1        - разворачивает %1 в полный квалифицированный путь
        %~d1        - разворачивает %1 в букву диска
        %~p1        - разворачивает %1 в путь
        %~n1        - разворачивает %1 в имя файла
        %~x1        - разворачивает %1 в расширение файла
        %~s1        - развернутый путь будет содержать только короткие имена
        %~a1        - разворачивает %1 в атрибуты файла
        %~t1        - разворачивает %1 в дату/время создания файла
        %~z1        - разворачивает %1 в размер файла
        %~$PATH:1   - Ищет в каталогах, перечисленных в переменной среды PATH,
                       и разворачивает %1 в полное квалифицированное имя 
                       первого совпадения. Если имя перменной среды
                       не определено, или если файл не найден, этот 
                       модификатор вернет пустую строку

и, более того:

    Модификаторы можно объединять для получения сложных результатов:

        %~dp1       - разворачивает %1 в букву диска и путь
        %~nx1       - разворачивает %1 в имя файла с расширением
        %~dp$PATH:1 – ищет %1 в каталогах, перечисленных в переменной 
                       среды PATH, и разворачивает в букву диска
                       и путь к первому найденному файлу.
        %~ftza1     - разворачивает %1 в строку, подобную DIR

Таким образом, правильным будет использовать в качестве тега <script-dir> сочетание %~dp0, которое будет раскрыто в полный путь к каталогу, где находится сценарий. Например,

      "%~dp0\packagebin.exe" --recursive-search=yes --files-mask=exe,dll,pdb,obj ^
    --archive-type=zip --archive-level=max --deliver-method=ftp            ^
    --deliver-target=ftp://ftp.site.com --deliver-source="%~dp0\bin"

Обратите внимание на использование кавычек – потенциально каталог может иметь в своем пути пробел. Кавычки избавят от проблем в этом случае.

ПРЕДУПРЕЖДЕНИЕ
Опасайтесь бездумного применения команды cd %~dp0 без проверки результата выполнения. Теоретически, эта команда должна сменить текущий каталог на каталог, в котором расположен командный файл. Как правило, это работает. Однако возможны неожиданности. Однажды был написан простой командный сценарий, задача которого была просто удалить все каталоги рядом с собой. В «свою» директорию он переходил как раз через cd %~dp0. Все было проверено на локальной машине – работало замечательно. После этого сценарий был помещен на файл-сервер, где ему и полагалось быть. Я зашел с помощью Far в сетевой каталог, и для контрольной проверки решил запустить файл еще раз. Дальнейшее словно в тумане. cmd.exe правильно определил местонахождение bat-файла: \\servername\sharename\directory. Однако при попытке сделать туда cd, он сказал, что UNC-пути в качестве текущих каталогов не поддерживаются и лучше он сменит текущий каталог на C:\WINDOWS… Это было действительно мудрое решение… Часть сценария, отвечавшая за удаление всех каталогов, сработала отлично – хорошо, что я успел вовремя остановить это безумие.В тот день я узнал, что такое System Restore…

Как получить короткое (8.3) имя файла?

«А зачем? – спросите вы – Ведь мы живем в мире Интернета, Web-сервисов и NTFS с длинными именами файлов». Это действительно так, но иногда встречаются программы, которые отчаянно сопротивляются прогрессу, и в частности, не любят имен файлов и полных путей с пробелами. Одной из таких программ, кстати, является утилита build.exe из Windows DDK… В таких ситуациях спасает использование короткого, «беспробельного» DOS-имени для файла.

ПРЕДУПРЕЖДЕНИЕ
Доступ к файлу по короткому имени может быть не всегда возможен. На файловой системе NTFS создание коротких псевдонимов для файлов может быть отключено путем установки в единицу значения «NtfsDisable8dot3NameCreation» в ключе реестра «HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem».

Итак, все же (в предположении, что надругательства над NTFS не было) – как? Внимательный читатель должен был заметить в предыдущем разделе, что при обращении к переменным %0 – %9 можно использовать префикс

%~s1        - expanded path contains short names only

который нам как раз мог бы помочь. Но есть засада – все эти полезные префиксы нельзя использовать с произвольной переменной окружения, а присваивание переменным %0 – %9 не поддерживается. К счастью, описываемые префиксы можно еще использовать с переменными цикла for, и это дает нам способ достичь требуемого результата. Например, вот так можно получить 8.3-путь к “Program Files”:

      for /d %%i in ("%PROGRAMFILES%") do (
    set PROGRAMFILESSHORT=%%~si
)

echo8.3-имя для каталога "%PROGRAMFILES%" -^> "%PROGRAMFILESSHORT%"

Этот и другие модификаторы можно использовать и с любой другой формой цикла for, подробнее о которых можно узнать из:

      for /?

Как перенаправить стандартный вывод в файл?

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

      echo
      Cleaning up the target directory >>%LOGFILE%
...
echoThe target directory has been cleaned >>%LOGFILE%

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

      @echo off
set OUTPUT=out.html

if "%STDOUT_REDIRECTED%" == "" (
    set STDOUT_REDIRECTED=yes
    cmd.exe /c %0 %* >%OUTPUT%
    exit /b %ERRORLEVEL%
)

echo^<html^>
echo^<head^>
echo^<title^>This is a greeting page^</title^>
echo^</head^>
echo^<body^>
echoHello World!
echo^</body^>
echo^</html^>

Здесь делается то же, что и раньше, но с перенаправлением стандартного вывода в файл out.html. Делается это простым способом – перезапуском сценарием самого себя. Сначала проверяется, не установлена ли переменная окружения STDOUT_REDIRECTED. Если она установлена, значит, сценарий уже перезапущен с перенаправленным выводом и можно просто продолжить работу. Если же переменная не установлена, то мы ее устанавливаем и перезапускаем скрипт (cmd.exe /c %0) с таким же набором параметров, что и исходная команда (%*) и перенаправленным в файл стандартным выводом (>%OUTPUT%). После завершения выполнения «перенаправленной» команды выходим.

Такое «единовременное» перенаправление имеет и еще один неочевидный плюс: файл открывается и закрывается только один раз, и всем командам и дочерним процессам передается дескриптор уже открытого файла. Во-первых, это чуть-чуть улучшит производительность (жизнь удалась – сроду бы не подумал, что буду когда-нибудь писать о производительности в bat-файлах). Во-вторых, это поможет избежать проблемы с невозможностью открыть файл для записи. Такое может случиться, если после выполнения одной из команд останется «висеть» какой-нибудь процесс. Он будет держать дескриптор интересующего нас файла и перенаправление вывода в этот файл для всех последующих команд провалится. Проблема может показаться надуманной, но однажды она украла у меня 2 часа жизни…

Как сложить два числа?

Краткий ответ – смотри:

      set /?

Длинный ответ таков. В bat-файлах можно производить довольно-таки продвинутые вычисления – продвинутые не в сравнении с другими языками, а в сравнении с отсутствием возможности что-либо вычислить вообще. Вычисление осуществляется командой set, если она выполняется с ключом /a. Поддерживается практически полный набор операторов языка C, включая шестнадцатеричный модификатор 0x. Переменные окружения в выражении не обязательно заключать в знаки процента – все, что не является числом, считается переменной. Подробнее – все-таки в man set, тьфу, то есть в set /?. А здесь напоследок – просто несколько примеров.

      @echo off

set ARG=1

rem Переменные окружения в выражении не обязательно заключать в %...%
set /a RESULT=ARG + 2
echo%RESULT%
remЕсли выражение содержит какие-либо из символов non grata, надо
remзаключить его в кавычкиset /a RESULT="ARG << 2"
echo%RESULT%
remШестнадцатеричная арифметика
set /a RESULT=0x1234 + 0x6786
echo%RESULT%
rem И многое-многое другое...

А можно создать в bat-файле функцию?

Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно. Есть особый синтаксис команды call, который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:

      call :метка аргументы

Возврат из функции производится командой:

      exit /b [опциональный код возврата]

Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще.

За подробностями обращайтесь к:

      call /?
exit /?

Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:

      @echo off

call :factorial %1
echo %RESULT%
exit
rem Функция для подсчета значения факториала
rem Вход:
rem       %1        Число, для которого необходимо подсчитать факториал
rem Выход:
rem       %RESULT%  Значение факториала
:factorial

if %1 == 0 (
    set RESULT=1
    exit /b
)

if %1 == 1 (
    set RESULT=1
    exit /b
)

set /a PARAM=%1 - 1

call :factorial %PARAM%

set /a RESULT=%1 * %RESULT%

exit /b

Пример работы:

> factorial.bat 10
3628800

Как можно избежать использования goto?

Любой хоть сколько-то осмысленный *.bat-файл длиной больше 50 строк является ярким лозунгом в поддержку работы Дейкстры «О вреде оператора goto». Мешанина из переходов вперед и назад действительно является кодом «только для записи». Можно ли что-то предпринять по этому поводу?

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

      if condition goto :THEN
rem Команды ветки ‘else’
rem ...
goto IF_END
:THEN
rem Команды ветки ‘then’
rem ...
:IF_END

Но к счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения меток. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):

      if condition (
    rem Команды ветки ‘then’
rem ...
) else (
    rem Команды ветки ‘else’
rem ...
)

Конкретный пример использования:

      @echo off

set BUILDMODE=%1

if "%BUILDMODE%" == "" (
    echoFAIL: Аргумент является обязательным ^(--debug, --release^)exit /b 1
)

rem Удаляем из аргумента все дефисы для упрощения обработки
set BUILDMODE=%BUILDMODE:-=%

if "%BUILDMODE%" == "debug" (
    echoINFO: Устанавливаем debug-режим окруженияset CCFLAGS=/Od /MDd /Z7
) else (
    echoINFO: Устанавливаем release-режим окруженияset CCFLAGS=/O2 /MD
)

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

      if "%BUILDMODE%" == "debug" (
    echoINFO: Устанавливаем debug-режим окружения
set OPTFLAGS=/Od
    set CCFLAGS=%OPTFLAGS% /MDd /Z7
) else (
    echoINFO: Устанавливаем release-режим окружения
set OPTFLAGS=/O2
    set CCFLAGS=%OPTFLAGS% /MD
)

Загвоздка в том, что в обоих блоках подстановка переменной OPTFLAGS произойдет до того, как она будет изменена в процессе выполнения этого блока. Соответственно, в CCFLAGS будет подставлено то значение, которое OPTFLAGS имела на момент начала выполнения данного if-блока.

Решается эта проблема путем использования отложенного раскрытия переменных. Переменные, заключенные в !…! вместо %…%, будут раскрыты в их значения только в момент непосредственного использования. Данный режим по умолчанию отключен. Включить его можно либо использованием ключа /V:ON при вызове cmd.exe, либо использованием команды

      setlocal enabledelayedexpansion

в тексте самого bat-файла. Второй способ мне представляется более удобным – не очень здорово требовать от кого-то запуска твоего сценария с определенным параметром.

С учетом сказанного предыдущий «неправильный» пример может быть исправлен так:

      setlocal enabledelayedexpansion

rem ...
if "%BUILDMODE%" == "debug" (
    echoINFO: Setting up debug mode environment
set OPTFLAGS=/Od
    set CCFLAGS=!OPTFLAGS! /MDd /Z7
) else (
    echoINFO: Setting up release mode environment
set OPTFLAGS=/O2
    set CCFLAGS=!OPTFLAGS! /MD
)

Вот теперь это почти полноценный if-then-else блок. Почти, потому что если в одной из команд echo у вас встретится закрывающая круглая скобка, то вам необходимо заэкранировать ее символом ^, иначе синтаксический анализатор путается…

Но в любом случае, это гораздо лучше безумного количества меток и переходов.

Как обработать текстовый файл?

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

Для привнесения еще большей конкретики в процесс изучения зададимся целью прочитать файл с настройками следующего содержания:

      # Это простой файл с настройками

      # Режим сборки
buildmode=release

# Компилятор
compiler=cl.exe

# Архитектура
arch=x86

Ничего сверхъестественного – простой key=value формат с возможностью вставки Unix-style комментариев. Помочь в чтении и обработке этого файла нам сможет команда for. Ее дополнительные опции позволяют задать и разделители, и символ начала комментария, и кое-что еще. Вот командный файл, который выполняет поставленную задачу:

      @echo off

rem Читаем настройки из файла settings.txt, который должен располагаться в
rem том же каталоге, что и bat-файл. Если не удалось распарсить настройки -
rem выходим с ненулевым кодом возврата.
call :read_settings %~dp0\settings.txt || exit /b 1

rem Прочитанные настройки:
echoBuild mode  : %BUILDMODE%echoCompiler    : %COMPILER%
echoArchitecture: %ARCH%
rem Выход из сценария. Дальше - только функции.
exit /b 0

remrem Функция для чтения настроек из файла.
rem Вход:
rem       %1           - Имя файла с настройками
:read_settings

set SETTINGSFILE=%1

rem Проверка существования файла
if not exist %SETTINGSFILE% (
    echoFAIL: Файл с настройками отсутствуетexit /b 1
)

rem Обработка файла c настройками
rem Здесь:
rem     eol=# указывает на то, что содержимое строки начиная с символа #
rem     и до ее конца может быть пропущено как комментарий.
remrem     delims== указывает, что разделителем значений является символ =
remrem     tokens=1,2 приводит к тому, что в переменную %%i будет занесен первый
rem     токен, а в %%j - второй.
remfor /f "eol=# delims== tokens=1,2" %%i in (%SETTINGSFILE%) do (
    rem В переменной i - ключ
rem В переменной j - значение
rem Мы транслируем это в переменные окружения
set %%i=%%j
)

exit /b 0

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

      for /?

Кстати, возможности команды for не ограничиваются чтением из файла. Возможно также чтение вывода другой команды. Например, так:

      @echo off

for /f "tokens=* usebackq" %%i in (`cmd.exe /c ver`) do (
    set VERSION=%%i
)

echo%VERSION%

Особенно меня умиляет наличие опции “usebackq”, которая делает синтаксис отдаленно похожим на юниксовый. И в стенах царства Билла есть граждане, скучающие по /bin/sh и пытающиеся хоть как-то скрасить существование свое и окружающих. Следующий совет это также косвенно подтверждает.

Что это за упомянутые ранее операторы объединения команд?

Это операторы &, && и ||. Они практически совсем не освещены в документации, но полезны в повседневности. Они позволяют объединять несколько команд в одну, т.е. примерно так:

command1 & command2
command1 && command2
command1 || command2

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

command1
command2

Оператор && гарантирует, что вторая команда будет выполнена только, если первая была выполнена успешно, т.е. с нулевым кодом возврата (он же %errorlevel%). Такие конструкции очень популярны в мире shell-сценариев Unix. Например:

      cd sources && make clean

Я был приятно удивлен, узнав, что cmd.exe тоже умеет выполнять такие конструкции. Это безопаснее и правильнее, нежели простое последовательное выполнение этих команд, и короче и проще, чем строгая проверка и обработка кодов возврата. Очень удобно при написании на скорую руку. Не менее полезен иногда и оператор ||. Суть его тоже логична – выполнить вторую команду, если первая дала сбой. Часто встречается в таких идиомах:

      cd sources || exit 1

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