*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

пятница, 29 июля 2011 г.

Работа с правами администратора

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

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

Как говорил один мой знакомый администратор, матерый ораклоид и юниксист: "Я никогда лишний раз в root'ом не зайду, а то вдруг чего надует (ветром)".

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

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

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

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

Увы, в Windows нереально работать, не будучи формально администратором, хотя в Windows 7 ситуация улучшилась. Когда я пересел с Windows XP на семерку, я стал регулярно отвечать на вопрос о том, что какая-то программа хочет сделать что-то с правами администратора (хотя мой пользователь есть администратор в понятии Windows), и лично мне это нравится. Есть какое-то минимальное ощущения контроля на тем, что кто-то больше не "размазывает" DLL'ки по системе без моего ведома, от которых ей скоро поплохеет.

воскресенье, 24 июля 2011 г.

Организация файлов на компьютере

Думаю, что у всех, кто работает с компьютером, есть какая-то стратегия организации файлов, а у программистов уж точно.

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

На Мак я пересел недавно, и рабочий ноутбук у меня все равно на Windows 7, то большинство приемов ориентированы на Windows.

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

Все рекомендации ниже движимы именно этой целью.

Один из подходов для решения обоих задач - сделать так, чтобы все мои файлы были доступны в иерархии одного единственного каталога. "Мои" означает, что в случае переезда на другой компьютер, данные файлы должны быть перенесены (не забыты). У меня есть каталог c:\moe (этимология английского "слова" moe утеряна). Двигаясь по этому каталогу вниз, можно найти все "мои" файлы, все-все. Также важно, что в каталоге c:\moe нет мусора, которым обычно загажен My Documents (всякие проекты-примеры, создаваемые Студией без спроса, мириады прочих папок "My..." от разных программ и т.д.). То есть это чистая полезная информация без неконтролируемого мусора.

К чему такие сложности? Не секрет, что в Windows расположение некоторых файлов "по умолчанию" весьма необычно, и далеко не все программы позволяют менять их расположение. Попробуйте найти базу данных Outlook Express или Microsoft Outlook, профайлы Thunderbird'а, Chrome'а или iTunes, настройки сессий SecureCRT и т.д. Все они обычно скрываются где-то в недрах c:\Users\your_user_name. Можно тупо бэкапить этот каталог, но, опять, там уж очень много неконтролируемого г*вна.

Итак, к помощью символьных ссылок я привел все нужные каталоги к простым путям. Например:

c:\moe\db\
          outlook\..
          thunderbird\..

       profiles\
                chrome\..
                securecrt\..
                itunes\..
                skype\..

Идем далее. Последнее время я стал люто ненавидеть программы, которые сохраняют конфигурацию и настройки в реестре. Я еще могу понять, что Microsoft Office пользуется реестром из-за "глубокой интеграции" в систему. Но вот почему Far или putty до сих пор не могут просто пользоваться текстовым файлом для настроек и сохранять его в c:\Users\... - непонятно. Для таких программ у меня написан скрипт, который командой reg копирует настройки нужных веток реестра в текстовые файлы. Что такого полезного есть в настройках Far? Например, ftp/sftp сессии. У меня их около сотни, и потерять их я не хочу.

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

c:\moe\live\
            7z-9.20\..
            hiew-8.00\..
            winrar-3.70\..
            xnview-1.98.2\..
            putty-0.60\..
            notepad++-5.9.2\..
            ...

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

Далее, каталог c:\moe\cmd. Тут лежат разные самодельные скрипты и однофайловые микро утилиты типа junction.exe. Этот каталог находится под контролем git, так как скрипты часто меняются, и хочется видеть историю изменений.

Каталог c:\moe\projects.

Тут лежит все, связанное с программированием. Иерархия этого каталога обычно одноуровневая: проект -> каталог. Одно условие (подтвержденное годами) - не использовать пробелы в именах каталогов. Сильно упрощает скриптование.

Например, c:\moe\projects\easy-coding\.

Также полезно сделать линк каталога c:\Program Files\ в c:\prg. Проще работать в скриптах с программами, установленными в этом каталоге.

Еще один каталог - c:\moe\documents.

Тут лежат то, что называется документами, без привязки к какому-то проекту: doc(x), xls(x), pdf, jpg и т.д. Тут уже допустимы имена с пробелами и русским буквами. Внутренняя иерархия - по смыслу. С документами на работе я часто создают подкаталоги в номером года. В них удобно убирать старье. Например:

c:\moe\documents\Team meetings\
                               2010\... <- Прошлый год
                               ...      <- Нынешняя текучка

Некоторое время назад я начал активно пользоваться атрибутом read-only. Если я вижу, что не меняю файл некоторое время, например, пару месяцев, то я делаю его read-only. Это относится и к проектам и к документам. Атрибут read-only позволяет исключить случайную перезапись старого файла, открытого для получения "примера" из прошлого. Ну а уж если захочется его таки изменить, то надо будет снимать флаг read-only или делать копию через "Save as...". Основная идея - старый файл не надо перезаписывать, так как история его создания может быть подзабыта, и можно случайно похерить важный файл. Все его производные должны быть сделаны через клонирование.

Кстати, в Mac OS Lion компания Apple сделала функцию "залочки" файлов, которые не менялись некоторое время.

Documents will also automatically be locked if they're not modified for a little while. The auto-lock time is configurable in the "Options…" screen of the Time Machine preference pane (of all places), with values from one day to one year. The default is two weeks.

Есть еще несколько каталогов:

  • c:\moe\books - книги
  • c:\moe\itunes - база данных iTunes
  • c:\moe\soft - архив программ (обычно дистрибутивы)
  • c:\moe\vm - виртуальные машины

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

Для физического осуществление бэкапа я использую nnbackup. Это весьма продвинутая программа, но я использую в ней только одну функцию односторонней синхронизации - при очередном сохранении каждый файл в каталоге c:\moe, который изменился, будет обновлен. Но выходе, еще раз, точная копия этого каталога на страховочном носителе.

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

P.S. Дополнительный довесок (чтобы два раза не вставать), который вроде бы как по теме, но не совсем. В той же статье про Lion описывается, что Apple ввели понятие версионности документов на уровне API. Я видел похожее в одной из систем разработки в Блумберге - в IDE не надо было принудительно сохранять файлы проекта. В любой момент времени среда обеспечивает сохранность файлов, и в случае зависания или прочих проблем при перезапуске открытые файлы автоматически восстанавливались из autosave'а. А вот если разработчик принудительно сохраняет файл (например, нажимает Ctrl-S), то файл не просто сохраняется, а делается commit в SVN с новой ревизией, и также приходится вводить описание этого изменения.

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

Я был приятно удивен, то в Lion схожий подход введен на уровне операционной системы. Тут, конечно, у Apple основная цель немного иная - они хотят тем самым полностью избавиться от вопросов о сохранении несохраненных документов при выходе из приложения, чтобы их (приложения), можно было незаметно для пользователя убивать и перезапускать заново, как в iOS. Забавно, что в Lion по умолчанию в Dock'е убрали индикатор запущенности приложения. Основной посыл такой - пользователя этот вопрос более не должен волновать. Операционная система запустит приложение, если требуется, и сама убьет его, если есть потребность в его ресурсах. Документы же, всегда будут в сохранности.

Кто еще поделится идеями и приемами организации файлов?

воскресенье, 17 июля 2011 г.

Переписывать или не переписывать

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


Как там у Шекспира: "переписывать или не переписывать - вот в чем вопрос". Можно приляпывать временные костыли там и сям, не давая зданию упасть, но придет время, когда законы физики возьмут свое, и здание таки нае*нется.

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

четверг, 14 июля 2011 г.

strcpy() для перекрывающихся строк

Рассмотрим программу:

#include <string.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
  char b[32];
  strcpy(b, "123456789012345");
  strcpy(b + 1, b);
  printf("[%s]\n", b);
  return 0;
}

Тут ясно видна проблема - строки, передаваемые в strcpy(), перекрываются.

По-хорошему, тут имеется неопределенное поведение, так как strcpy() не гарантирует порядок перемещения байт, а именно от него зависит в данном случае результат.

Проверим на разных компиляторах и платформах.

Visual Studio 2010 64-bit

[1123446788012245]

Строка искажается каждые четыре байта, явно копировали по 32 бита.

Linux 64-bit

[1123456788012345]

Уже иной результат. Компилятор и libc:

ldd --version
ldd (GNU libc) 2.5

gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50)

В "man strcpy" говорят:

The strings may not overlap...

Странно, почему не "must not".

Solaris (SPARC)

[1123446788012245]

Компилятор и libc:

cc -V
cc: Sun C 5.8 2005/10/13

version /usr/lib/libC*
version of "/usr/lib/libC.so.3": SC2.0.1 12/20/94 Sun C++ 3.0.1 patch 100962-09
version of "/usr/lib/libC.so.5": Sun SUNWlibC SunOS 5.10 Patch 119963-06 2006/04/21
version of "/usr/lib/libCrun.so.1": Sun SUNWlibC SunOS 5.10 Patch 119963-06 2006/04/21
version of "/usr/lib/libCstd.so.1": Sun SUNWlibC SunOS 5.10 Patch 119963-06 2006/04/21

AIX

[1111111111012245]

Тут результат явно левый. Но зато в документации сказано ясно и понятно:

String movement is performed on a character-by-character basis and starts at the left. Overlapping moves toward the left work as expected, but overlapping moves to the right may give unexpected results.

Компилятор и libc:

lslpp -L | grep Compiler
vacpp.cmp.core            8.0.0.20    C     F    IBM XL C/C++ Compiler

lslpp -L | grep libc
bos.rte.libc               5.3.9.1    C     F    libc Library

HP-UX

[1123456789012345]

Компилятор:

what `which cc`

HP C/aC++ for Integrity Servers B3910B A.06.22 [Nov 14 2008]

Вроде скопировано правильно, но в документации (man strcpy) говорят (формулировка интересна):

Character movement is performed differently in different implementations, so moves involving overlapping source and destination strings may yield surprises.

Вывод: strcpy() - нехорошая функция, по многим причинам.