Quantcast
Channel: uzverss
Viewing all 433 articles
Browse latest View live

О GCC, компиляции и библиотеках часть 1

$
0
0


GCC - GNU Compiler Collection - набор компиляторов и сопутствующих утилит, разработанный в рамках движения GNU. GCC один из старейших Open Source проектов, первый релиз состоялся в 1985 году, автор сам Ричард Столлман. В исходном варианте поддерживал только язык C и аббревиатура GCC расшифровывалась как GNU C Compiler. Постепенно набор доступных языков расширялся, были добавлены компиляторы Fortran, C++, Ada. С уверенностью можно сказать, что современный мир Open Source обязан своим рождением GCC (по крайней мере без GCC он был бы другим). В настоящее время проект находиться под крылом Free Software Foundation. GCC выпускается под лицензией GPLv3 и является стандартным компилятором для большинства свободных UNIX-подобных операционных систем. В базовый набор входят компиляторы языков: C, C++, Objective-C, Java, Fortran, Ada. GCC поддерживает все основные процессорные архитектуры. Официальный сайт проекта gcc.gnu.org

Основы


GCC входит в состав любого дистрибутива Linux и, как правило, устанавливается по умолчанию. Интерфейс GCC, это стандартный интерфейс компилятора на UNIX платформе, уходящий своими корнями в конец 60-х, начало 70-х годов прошлого века - интерфейс командной строки. Не стоит пугаться, за прошедшее время механизм взаимодействия с пользователем был отточен до возможного в данном случае совершенства, и работать с GCC (при наличии нескольких дополнительных утилит и путного текстового редактора) проще, чем с любой из современных визуальных IDE. Авторы набора постарались максимально автоматизировать процесс компиляции и сборки приложений. Пользователь вызывает управляющую программу gcc, она интерпретирует переданные аргументы командной строки (опции и имена файлов) и для каждого входного файла, в соответствии с использованным языком программирования, запускает свой компилятор, затем, если это необходимо, gcc автоматически вызывает ассемблер и линковщик (компоновщик).

Любопытно, компиляторы одни из немногих приложений UNIX для которых не безразлично расширение файлов. По расширению GCC определяет что за файл перед ним и, что с ним нужно (можно) сделать. Файлы исходного кода на языке C должны иметь расширение .c, на языке C++, как вариант, .cpp, заголовочные файлы на языке C .h, объектные файлы .o и так далее. Если использовать неправильное расширение, gcc будет работать не корректно (если вообще согласиться, что-либо делать).

Перейдём к практике. Напишем, откомпилируем и исполним какую-нибудь незамысловатую программу. Не будем оригинальничать, в качестве исходного файла примера программы на языке C сотворим файл с вот таким содержимым:
/* hello.c */

#include <stdio.h>

main(void)
{

        printf("Hello World\n");

        return 0;

}

Теперь в каталоге c hello.c отдадим команду:

$ gcc hello.c

Через несколько долей секунды в каталоге появиться файл a.out:

$ ls
a.out hello.c

Это и есть готовый исполняемый файл нашей программы. По умолчанию gcc присваивает выходному исполняемому файлу имя a.out (когда-то очень давно это имя означало assembler output).



Запустим получившийся программный продукт:

$ ./a.out
Hello World

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

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

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

Почему не рекомендуется вносить . в PATH? Считается, что в реальной многопользовательской системе всегда найдется какой-нибудь нехороший человек, который разместит в общедоступном каталоге вредоносную программу с именем исполняемого файла, совпадающим с именем какой-нибудь команды, часто вызываемой местным администратором с правами суперпользователя... Заговор удастся если . стоит в начале списка каталогов.

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

$ file hello.c
hello.c: ASCII C program text
$ file annotation.doc
annotation.doc: CDF V2 Document, Little Endian, Os: Windows, Version 5.1, Code page: 1251, Author: MIH, Template: Normal.dot, Last Saved By: MIH, Revision Number: 83, Name of Creating Application: Microsoft Office Word, Total Editing Time: 09:37:00, Last Printed: Thu Jan 22 07:31:00 2009, Create Time/Date: Mon Jan 12 07:36:00 2009, Last Saved Time/Date: Thu Jan 22 07:34:00 2009, Number of Pages: 1, Number of Words: 3094, Number of Characters: 17637, Security: 0

Вот собственно и всё, что требуется от пользователя для успешного применения gcc :)

Имя выходного исполняемого файла (как впрочем и любого другого файла формируемого gcc) можно изменить с помощью опции -o:

$ gcc -o hello hello.c
$ ls
hello hello.c
$ ./hello
Hello World

В нашем примере функция main() возвращает казалось бы ни кому не нужное значение 0. В UNIX-подобных системах, по завершении работы программы, принято возвращать в командную оболочку целое число - в случае успешного завершения ноль, любое другое в противном случае. Интерпретатор оболочки автоматически присвоит полученное значение переменной среды с именем ?. Просмотреть её содержимое можно с помощью команды echo $?:

$ ./hello
Hello World
$ echo $?
0

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

Процесс компиляции можно разбить на 4 основных этапа: обработка препроцессором, собственно компиляция, ассемблирование, линковка (связывание).

Опции gcc позволяют прервать процесс на любом из этих этапов.

Препроцессор осуществляет подготовку исходного файла к компиляции - вырезает комментарии, добавляет содержимое заголовочных файлов (директива препроцессора #include), реализует раскрытие макросов (символических констант, директива препроцессора #define).

Воспользовавшись опцией -E дальнейшие действия gcc можно прервать и просмотреть содержимое файла, обработанного препроцессором.
$ gcc -E -o hello.i hello.c
$ ls
hello.c  hello.i
$ less hello.i
. . .
# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
. . .
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
. . .
extern int printf (__const char *__restrict __format, ...);
. . .
# 4 "hello.c" 2
 
main (void)
{
 
 printf ("Hello World\n");
 
 return 0;
 
}

После обработки препроцессором исходный текст нашей программы разбух и приобрел не удобочитаемый вид. Код, который мы когда-то собственноручно набили, свелся к нескольким строчкам в самом конце файла. Причина - подключение заголовочного файла стандартной библиотеки C. Заголовочный файл stdio.h сам по себе содержит много всего разного да ещё требует включения других заголовочных файлов.

Обратите внимание на расширение файла hello.i. По соглашениям gcc расширение .i соответствует файлам с исходным кодом на языке C не требующим обработки препроцессором. Такие файлы компилируются минуя препроцессор:

$ gcc -o hello hello.i
$ ls
hello hello.c hello.i
$ ./hello
Hello World

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

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

Остановить процесс создания исполняемого файла по завершении компиляции позволяет опция -S:
$ gcc -S hello.c
$ ls
hello.c  hello.s
$ file hello.s
hello.s: ASCII assembler program text
$ less hello.s
        .file   "hello.c"
        .section        .rodata
.LC0:
        .string "Hello World"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $16, %esp
        movl    $.LC0, (%esp)
        call    puts
        movl    $0, %eax
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

В каталоге появился файл hello.s, содержащий реализацию программы на языке ассемблера. Обратите внимание, задавать имя выходного файла с помощью опции -o в данном случае не потребовалось, gcc автоматически его сгенерировал, заменив в имени исходного файла расширение .c на .s. Для большинства основных операций gcc имя выходного файла формируется путем подобной замены. Расширение .s стандартное для файлов с исходным кодом на языке ассемблера.

Получить исполняемый код разумеется можно и из файла hello.s:

$ gcc -o hello hello.s
$ ls
hello hello.c hello.s
$ ./hello
Hello World

Следующий этап операция ассмеблирования - трансляция кода на языке ассемблера в машинный код. Результат операции - объектный файл. Объектный файл содержит блоки готового к исполнению машинного кода, блоки данных, а также список определенных в файле функций и внешних переменных (таблицу символов), но при этом в нем не заданы абсолютные адреса ссылок на функции и данные. Объектный файл не может быть запущен на исполнение непосредственно, но в дальнейшем (на этапе линковки) может быть объединен с другими объектными файлами (при этом, в соответствии с таблицами символов, будут вычислены и заполнены адреса существующих между файлами перекрестных ссылок). Опция gcc -c, останавливает процесс по завершении этапа ассемблирования:

$ gcc -c hello.c
$ ls
hello.c hello.o
$ file hello.o
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

Для объектных файлов принято стандартное расширение .o.

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

$ gcc -o hello hello.o
$ ls
hello hello.c hello.o
$ ./hello
Hello World

То, что мы сейчас проделали (вернее gcc проделал за нас) и есть содержание последнего этапа - линковки (связывания, компоновки).

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

Опция -Iпуть/к/каталогу/с/заголовочными/файлами - добавляет указанный каталог к списку путей поиска заголовочных файлов. Каталог, добавленный опцией -I просматривается первым, затем поиск продолжается в стандартных системных каталогах. Если опций -I несколько, заданные ими каталоги просматриваются слева на право, по мере появления опций.

Опция -Wall - выводит предупреждения, вызванные потенциальными ошибками в коде, не препятствующими компиляции программы, но способными привести, по мнению компилятора, к тем или иным проблемам при её исполнении. Важная и полезная опция, разработчики gcc рекомендуют пользоваться ей всегда. Например масса предупреждений будет выдана при попытке компиляции вот такого файла:
 1 /* remark.c */
 2 
 3 static int k = 0;
 4 static int l(int a);
 5 
 6 main()
 7 {
 8 
 9         int a;
10 
11         int b, c;
12 
13         b + 1;
14 
15         b = c;
16 
17         int *p;
18 
19         b = *p;
20 
21 }

$ gcc -o remark remark.c
$ gcc -Wall -o remark remark.c
remark.c:7: warning: return type defaults to ‘int’
remark.c: In function ‘main’:
remark.c:13: warning: statement with no effect
remark.c:9: warning: unused variable ‘a’
remark.c:21: warning: control reaches end of non-void function
remark.c: At top level:
remark.c:3: warning: ‘k’ defined but not used
remark.c:4: warning: ‘l’ declared ‘static’ but never defined
remark.c: In function ‘main’:
remark.c:15: warning: ‘c’ is used uninitialized in this function
remark.c:19: warning: ‘p’ is used uninitialized in this function

Опция -Werror - превращает все предупреждения в ошибки. В случае появления предупреждения прерывает процесс компиляции. Используется совместно с опцией -Wall.

$ gcc -Werror -o remark remark.c
$ gcc -Werror -Wall -o remark remark.c
cc1: warnings being treated as errors
remark.c:7: error: return type defaults to ‘int’
remark.c: In function ‘main’:
remark.c:13: error: statement with no effect
remark.c:9: error: unused variable ‘a’

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

Опции -O1, -O2, -O3 - задают уровень оптимизации кода генерируемого компилятором. С увеличением номера, степень оптимизации возрастает. Действие опций можно увидеть вот на таком примере.

Исходный файл:
/* circle.c */

main(void)
{

        int i;

        for(i = 0; i < 10; ++i)
                ;

        return i;

}

Компиляция с уровнем оптимизации по умолчанию:


$ gcc -S circle.c
$ less circle.s
        .file   "circle.c"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    $0, -4(%ebp)
        jmp     .L2
.L3:
        addl    $1, -4(%ebp)
.L2:
        cmpl    $9, -4(%ebp)
        jle     .L3
        movl    -4(%ebp), %eax
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

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


$ gcc -S -O3 circle.c
$ less circle.s
        .file   "circle.c"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    $10, %eax
        movl    %esp, %ebp
        popl    %ebp
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

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

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

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

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

Опция -march=architecture - задает целевую архитектуру процессора. Список поддерживаемых архитектур обширен, например, для процессоров семейства Intel/AMD можно задать i386, pentium, prescott, opteron-sse3 и т.д. Пользователи бинарных дистрибутивов должны иметь в виду, что для корректной работы программ с указанной опцией желательно, что бы и все подключаемые библиотеки были откомпилированы с той же опцией.

Об опциях передаваемых линковщику будет сказано ниже.

Собственно о компиляции все. Далее поговорим о раздельной компиляции и создании библиотек.

Небольшое дополнение:

Выше было сказано, что gcc определяет тип (язык программирования) переданных файлов по их расширению и, в соответствии с угаданным типом (языком), производит действия над ними. Пользователь обязан следить за расширениями создаваемых файлов, выбирая их так, как того требуют соглашения gcc. В действительности gcc можно подсовывать файлы с произвольными именами. Опция gcc -x позволяет явно указать язык программирования компилируемых файлов. Действие опции распространяется на все последующие перечисленные в команде файлы (вплоть до появления следующей опции -x). Возможные аргументы опции:
c                 c-header                 c-cpp-output

c++               c++-header               c++-cpp-output

objective-c       objective-c-header       objective-c-cpp-output

objective-c++     objective-c++-header     objective-c++-cpp-output

assembler         assembler-with-cpp

ada

f77               f77-cpp-input

f95               f95-cpp-input

java

Назначение аргументов должно быть понятно из их написания (здесь cpp не имеет ни какого отношения к C++, это файл исходного кода предварительно обработанный препроцессором). Проверим:

$ mv hello.c hello.txt
$ gcc -Wall -x c -o hello hello.txt
$ ./hello
Hello World

Раздельная компиляция



Сильной стороной языков C/C++ является возможность разделять исходный код программы по нескольким файлам. Даже можно сказать больше - возможность раздельной компиляции это основа языка, без неё эффективное использование C не мыслимо. Именно мультифайловое программирование позволяет реализовать на C крупные проекты, например такие как Linux (здесь под словом Linux подразумевается как ядро, так и система в целом). Что даёт раздельная компиляция программисту?

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

2. Позволяет сократить время повторной компиляции проекта. Если изменения внесены в один файл нет смысла перекомпилировать весь проект, достаточно заново откомпилировать только этот изменённый файл.

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

4. Без раздельной компиляции не существовало бы библиотек. Посредством библиотек реализовано повторное использование и распространение кода на C/C++, причем кода бинарного, что позволяет с одной стороны предоставить разработчикам простой механизм включения его в свои программы, с другой стороны скрыть от них конкретные детали реализации. Работая над проектом, всегда стоит задумываться над тем, а не понадобиться что-либо из уже сделанного когда-нибудь в будущем? Может стоит заранее выделить и оформить часть кода как библиотеку? По моему, такой подход, существенно упрощает жизнь и экономит массу времени.

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

Вот практический пример (правда весьма и весьма условный).

Набор файлов исходного кода:
/* main.c */

#include <stdio.h>

#include "first.h"
#include "second.h"

int main(void)
{

        first();
        second();

        printf("Main function...\n");

        return 0;

}

/* first.h */

void first(void);

/* first.c */

#include <stdio.h>

#include "first.h"

void first(void)
{

        printf("First function...\n");

}

/* second.h */

void second(void);

/* second.c */

#include <stdio.h>

#include "second.h"

void second(void)
{

        printf("Second function...\n");

}

В общем имеем вот что:

$ ls
first.c first.h main.c second.c second.h
Все это хозяйство можно скомпилировать в одну команду:

$ gcc -Wall -o main main.c first.c second.c
$ ./main
First function...
Second function...
Main function...

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

$ gcc -Wall -c main.c
$ gcc -Wall -c first.c
$ gcc -Wall -c second.c
$ ls
first.c first.h first.o main.c main.o second.c second.h second.o
$ gcc -o main main.o first.o second.o
$ ./main
First function...
Second function...
Main function...

Что мы сделали? Из каждого исходного файла (компилируя с опцией -c) получили объектный файл. Затем объектные файлы слинковали в итоговый исполняемый. Разумеется команд gcc стало больше, но в ручную ни кто проекты не собирает, для этого есть утилиты сборщики (самая популярная make). При использовании утилит сборщиков и проявятся все из перечисленных выше преимуществ раздельной компиляции.

Возникает вопрос: как линковщик ухитряется собирать вместе объектные файлы, правильно вычисляя адресацию вызовов? Откуда он вообще узнаёт, что в файле second.o содержится код функции second(), а в коде файла main.o присутствует её вызов? Оказывается всё просто - в объектном файле присутствует так называемая таблица символов, включающая имена некоторых позиций кода (функций и внешних переменных). Линковщик просматривает таблицу символов каждого объектного файла, ищет общие (с совпадающими именами) позиции, на основании чего делает выводы о фактическом местоположении кода используемых функций (или блоков данных) и, соответственно, производит перерасчёт адресов вызовов в исполняемом файле.

Просмотреть таблицу символов можно с помощью утилиты nm.
$ nm main.o
         U first
00000000 T main
         U puts
         U second
$ nm first.o
00000000 T first
         U puts
$ nm second.o
         U puts
00000000 T second

Появление вызова puts объясняется использованием функции стандартной библиотеки printf(), превратившейся в puts() на этапе компиляции.

Таблица символов прописывается не только в объектный, но и в исполняемый файл:
$ nm main
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484fc R _IO_stdin_used
         w _Jv_RegisterClasses
08049f10 d __CTOR_END__
08049f0c d __CTOR_LIST__
08049f18 D __DTOR_END__
08049f14 d __DTOR_LIST__
08048538 r __FRAME_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
0804a014 A __bss_start
0804a00c D __data_start
080484b0 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
         w __gmon_start__
080484aa T __i686.get_pc_thunk.bx
08049f0c d __init_array_end
08049f0c d __init_array_start
08048440 T __libc_csu_fini
08048450 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
0804a014 A _edata
0804a01c A _end
080484dc T _fini
080484f8 R _fp_hw
080482b8 T _init
08048330 T _start
0804a014 b completed.7021
0804a00c W data_start
0804a018 b dtor_idx.7023
0804840c T first
080483c0 t frame_dummy
080483e4 T main
         U puts@@GLIBC_2.0
08048420 T second

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

$ gcc -s -o main main.o first.o second.o
$ ./main
First function...
Second function...
Main function...
$ nm main
nm: main: no symbols

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

http://pyviy.blogspot.ru/2010/12/gcc.html


О GCC, компиляции и библиотеках часть 2

$
0
0

Библиотеки


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

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

С точки зрения операционной системы и прикладного программного обеспечения библиотеки бывают статическими и разделяемыми (динамическими).

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

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

Парадигма разделяемых библиотек предоставляет три существенных преимущества:

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

2. Код разделяемой библиотеки используемый несколькими приложениями храниться в оперативной памяти в одном экземпляре (на самом деле не всё так просто...), в результате сокращается потребность системы в доступной оперативной памяти.

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

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

Теперь немного практики.



Для иллюстрации воспользуемся набором исходных файлов из предыдущего примера. В нашу самодельную библиотеку поместим код (реализацию) функций first() и second().

В Linux принята следующая схема именования файлов библиотек (хотя соблюдается она не всегда) - имя файла библиотеки начинается с префикса lib, за ним следует собственно имя библиотеки, в конце расширение .a (archive) - для статической библиотеки, .so (shared object) - для разделяемой (динамической), после расширения через точку перечисляются цифры номера версии (только для динамической библиотеки). Имя, соответствующего библиотеке заголовочного файла (опять же как правило), состоит из имени библиотеки (без префикса и версии) и расширения .h. Например: libogg.a, libogg.so.0.7.0, ogg.h.

В начале создадим и используем статическую библиотеку.



Функции first() и second() составят содержимое нашей библиотеки libhello. Имя файла библиотеки, соответственно, будет libhello.a. Библиотеке сопоставим заголовочный файл hello.h.
/* hello.h */

void first(void);
void second(void);
Разумеется, строки:

#include "first.h"

#include "second.h"в файлах main.c, first.c и second.c необходимо заменить на:

#include "hello.h"Ну а теперь, введем следующую последовательность команд:

$ gcc -Wall -c first.c
$ gcc -Wall -c second.c
$ ar crs libhello.a first.o second.o
$ file libhello.a
libhello.a: current ar archive

Как уже было сказано - библиотека это набор объектных файлов. Первыми двумя командами мы и создали эти объектные файлы.

Далее необходимо объектные файлы скомпоновать в набор. Для этого используется архиватор ar - утилита "склеивает"несколько файлов в один, в полученный архив включает информацию требуемую для восстановления (извлечения) каждого индивидуального файла (включая его атрибуты принадлежности, доступа, времени). Какого-либо "сжатия"содержимого архива или иного преобразования хранимых данных при этом не производится.

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

Опция r - задает режим обновления архива, если в архиве файл с указанным именем уже существует, он будет удален, а новый файл дописан в конец архива.

Опция s - добавляет (обновляет) индекс архива. В данном случае индекс архива это таблица, в которой для каждого определенного в архивируемых файлах символического имени (имени функции или блока данных) сопоставлено соответствующее ему имя объектного файла. Индекс архива необходим для ускорения работы с библиотекой - для того чтобы найти нужное определение, отпадает необходимость просматривать таблицы символов всех файлов архива, можно сразу перейти к файлу, содержащему искомое имя. Просмотреть индекс архива можно с помощью уже знакомой утилиты nm воспользовавшись её опцией -s (так же будут показаны таблицы символов всех объектных файлов архива):
$ nm -s libhello.a
Archive index:
first in first.o
second in second.o

first.o:
00000000 T first
         U puts

second.o:
         U puts
00000000 T second

Для создания индекса архива существует специальная утилита ranlib. Библиотеку libhello.a можно было сотворить и так:

$ ar cr libhello.a first.o second.o
$ ranlib libhello.a

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

Теперь воспользуемся нашей библиотекой:

$ gcc -Wall -c main.c
$ gcc -o main main.o -L. -lhello
$ ./main
First function...
Second function...
Main function...
Работает...

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

Опция -lname - передаётся линковщику, указывает на необходимость подключить к исполняемому файлу библиотеку libname. Подключить значит указать, что такие-то и такие-то функции (внешние переменные) определены в такой-то библиотеке. В нашем примере библиотека статическая, все символьные имена будут ссылаться на код находящийся непосредственно в исполняемом файле. Обратите внимание в опции -l имя библиотеки задается как name без приставки lib.

Опция -L/путь/к/каталогу/с/библиотеками - передаётся линковщику, указывает путь к каталогу содержащему подключаемые библиотеки. В нашем случае задана точка ., линковщик сначала будет искать библиотеки в текущем каталоге, затем в каталогах определённых в системе.

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

$ gcc -Wall -c main.c
$ gcc -o main -L. -lhello main.o
main.o: In function `main':
main.c:(.text+0xa): undefined reference to `first'
main.c:(.text+0xf): undefined reference to `second'
collect2: ld returned 1 exit status
$ gcc -o main main.o -L. -lhello
$ ./main
First function...
Second function...
Main function...

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

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

$ echo $LD_LIBRARY_PATH

$ gcc -o main main.o -lhello
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lhello
collect2: выполнение ld завершилось с кодом возврата 1
$ export LIBRARY_PATH=.
$ gcc -o main main.o -lhello
$ ./main
First function...
Second function...
Main function...

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

Теперь создадим и используем библиотеку динамическую.

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

$ gcc -Wall -fPIC -c first.c
$ gcc -Wall -fPIC -c second.c
$ gcc -shared -o libhello.so.2.4.0.5 -Wl,-soname,libhello.so.2 first.o second.o

Что получили в результате?

$ file libhello.so.2.4.0.5
libhello.so.2.4.0.5: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

Файл libhello.so.2.4.0.5, это и есть наша разделяемая библиотека. Как её использовать поговорим чуть ниже.

Теперь комментарии:

Опция -fPIC - требует от компилятора, при создании объектных файлов, порождать позиционно-независимый код (PIC - Position Independent Code), его основное отличие в способе представления адресов. Вместо указания фиксированных (статических) позиций, все адреса вычисляются исходя из смещений заданных в глобальной таблицы смещений (global offset table - GOT). Формат позиционно-независимого кода позволяет подключать исполняемые модули к коду основной программы в момент её загрузки. Соответственно, основное назначение позиционно-независимого кода - создание динамических (разделяемых) библиотек.

Опция -shared - указывает gcc, что в результате должен быть собран не исполняемый файл, а разделяемый объект - динамическая библиотека.

Опция -Wl,-soname,libhello.so.2 - задает soname библиотеки. О soname подробно поговорим в следующем абзаце. Сейчас обсудим формат опции. Сея странная, на первый взгляд, конструкция с запятыми предназначена для непосредственного взаимодействия пользователя с линковщиком. По ходу компиляции gcc вызывает линковщик автоматически, автоматически же, по собственному усмотрению, gcc передает ему необходимые для успешного завершения задания опции. Если у пользователя возникает потребность самому вмешаться в процесс линковки он может воспользоваться специальной опцией gcc -Wl,-option,value1,value2.... Что означает передать линковщику (-Wl) опцию -option с аргументами value1, value2 и так далее. В нашем случае линковщику была передана опция -soname с аргументом libhello.so.2.

Теперь о soname. При создании и распространении библиотек встает проблема совместимости и контроля версий. Для того чтобы система, конкретно загрузчик динамических библиотек, имели представление о том библиотека какой версии была использована при компиляции приложения и, соответственно, необходима для его успешного функционирования, был предусмотрен специальный идентификатор - soname, помещаемый как в файл самой библиотеки, так и в исполняемый файл приложения. Идентификатор soname это строка, включающая имя библиотеки с префиксом lib, точку, расширение so, снова точку и оду или две (разделенные точкой) цифры версии библиотеки - libname.so.x.y. То есть soname совпадает с именем файла библиотеки вплоть до первой или второй цифры номера версии. Пусть имя исполняемого файла нашей библиотеки libhello.so.2.4.0.5, тогда soname библиотеки может быть libhello.so.2. При изменении интерфейса библиотеки её soname необходимо изменять! Любая модификация кода, приводящая к несовместимости с предыдущими релизами должна сопровождаться появлением нового soname.

Как же это все работает? Пусть для успешного исполнения некоторого приложения необходима библиотека с именем hello, пусть в системе таковая имеется, при этом имя файла библиотеки libhello.so.2.4.0.5, а прописанное в нем soname библиотеки libhello.so.2. На этапе компиляции приложения, линковщик, в соответствии с опцией -lhello, будет искать в системе файл с именем libhello.so. В реальной системе libhello.so это символическая ссылка на файл libhello.so.2.4.0.5. Получив доступ к файлу библиотеки, линковщик считает прописанное в нем значение soname и наряду с прочим поместит его в исполняемый файл приложения. Когда приложение будет запущено, загрузчик динамических библиотек получит запрос на подключение библиотеки с soname, считанным из исполняемого файла, и попытается найти в системе библиотеку, имя файла которой совпадает с soname. То есть загрузчик попытается отыскать файл libhello.so.2. Если система настроена корректно, в ней должна присутствовать символическая ссылка libhello.so.2 на файл libhello.so.2.4.0.5, загрузчик получит доступ к требуемой библиотеки и далее не задумываясь (и ни чего более не проверяя) подключит её к приложению. Теперь представим, что мы перенесли откомпилированное таким образом приложение в другую систему, где развернута только предыдущая версия библиотеки с soname libhello.so.1. Попытка запустить программу приведет к ошибке, так как в этой системе файла с именем libhello.so.2 нет.

Таким образом, на этапе компиляции линковщику необходимо предоставить файл библиотеки (или символическую ссылку на файл библиотеки) с именем libname.so, на этапе исполнения загрузчику потребуется файл (или символическая ссылка) с именем libname.so.x.y. При чем имя libname.so.x.y должно совпадать со строкой soname использованной библиотеки.

В бинарных дистрибутивах, как правило, файл библиотеки libhello.so.2.4.0.5 и ссылка на него libhello.so.2 будут помещены в пакет libhello, а необходимая только для компиляции ссылка libhello.so, вместе с заголовочным файлом библиотеки hello.h будет упакована в пакет libhello-devel (в devel пакете окажется и файл статической версии библиотеки libhello.a, статическая библиотека может быть использована, также только на этапе компиляции). При распаковке пакета все перечисленные файлы и ссылки (кроме hello.h) окажутся в одном каталоге.

Пример именования библиотек в Linux. Ubuntu

Пример именования библиотек в Linux. Ubuntu
Убедимся, что заданная строка soname действительно прописана в файле нашей библиотеки. Воспользуемся мега утилитой objdump с опцией -p:
$ objdump -p libhello.so.2.4.0.5 | grep SONAME
  SONAME               libhello.so.2

Утилита objdump - мощный инструмент, позволяющий получить исчерпывающую информацию о внутреннем содержании (и устройстве) объектного или исполняемого файла. В man странице утилиты сказано, что objdump прежде всего будет полезен программистам, создающими средства отладки и компиляции, а не просто пишущих какие-нибудь прикладные программы :) В частности с опцией -d это дизассемблер. Мы воспользовались опцией -p - вывести различную метаинформацию о объектном файле.

В приведенном примере создания библиотеки мы неотступно следовали принципам раздельной компиляции. Разумеется скомпилировать библиотеку можно было бы и вот так, одним вызовом gcc:

$ gcc -shared -Wall -fPIC -o libhello.so.2.4.0.5 -Wl,-soname,libhello.so.2 first.c second.c

Теперь попытаемся воспользоваться получившейся библиотекой:

$ gcc -Wall -c main.c
$ gcc -o main main.o -L. -lhello -Wl,-rpath,.
/usr/bin/ld: cannot find -lhello
collect2: ld returned 1 exit status

Линковщик ругается. Вспоминаем, что было сказано выше о символических ссылках. Создаем libhello.so и повторяем попытку:

$ ln -s libhello.so.2.4.0.5 libhello.so
$ gcc -o main main.o -L. -lhello -Wl,-rpath,.

Теперь все довольны. Запускаем созданный бинарник:

$ ./main
./main: error while loading shared libraries: libhello.so.2: cannot open shared object file: No such file or directory

Ошибка... Ругается загрузчик, не может найти библиотеку libhello.so.2. Убедимся, что в исполняемом файле действительно прописана ссылка на libhello.so.2:
$ objdump -p main | grep NEEDED
  NEEDED               libhello.so.2
  NEEDED               libc.so.6

Создаем соответствующую ссылку и повторно запускаем приложение:

$ ln -s libhello.so.2.4.0.5 libhello.so.2
$ ./main
First function...
Second function...
Main function...

Заработало... Теперь комментарии по новым опциям gcc.

Опция -Wl,-rpath,. - уже знакомая конструкция, передать линковщику опцию -rpath с аргументом .. С помощью -rpath в исполняемый файл программы можно прописать дополнительные пути по которым загрузчик разделяемых библиотек будет производить поиск библиотечных файлов. В нашем случае прописан путь . - поиск файлов библиотек будет начинаться с текущего каталога.
$ objdump -p main | grep RPATH
  RPATH                .

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

$ mv main ..
$ ../main
First function...
Second function...
Main function...
$ cd ..
$ ./main
./main: error while loading shared libraries: libhello.so.2: cannot open shared object file: No such file or directory

Узнать какие разделяемые библиотеки необходимы приложению можно и с помощью утилиты ldd:

$ ldd main
linux-vdso.so.1 => (0x00007fffaddff000)
libhello.so.2 => ./libhello.so.2 (0x00007f9689001000)
libc.so.6 => /lib/libc.so.6 (0x00007f9688c62000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9689205000)

В выводе ldd для каждой требуемой библиотеки указывается её soname и полный путь к файлу библиотеки, определённый в соответствии с настройками системы.

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

В соответствии с соглашениями FHS (Filesystem Hierarchy Standard)в системе должны быть два (как минимум) каталога для хранения файлов библиотек:

/lib - здесь собраны основные библиотеки дистрибутива, необходимые для работы программ из /bin и /sbin;

/usr/lib - здесь хранятся библиотеки необходимые прикладным программам из /usr/bin и /usr/sbin;

Соответствующие библиотекам заголовочные файлы должны находиться в каталоге /usr/include.

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

Кроме перечисленных выше, в системе должен присутствовать каталог /usr/local/lib - здесь должны находиться библиотеки, развернутые пользователем самостоятельно, минуя систему управления пакетами (не входящие в состав дистрибутива). Например в этом каталоге по умолчанию окажутся библиотеки скомпилированные из исходников (программы установленные из исходников будут размещены в /usr/local/bin и /usr/local/sbin, разумеется речь идет о бинарных дистрибутивах). Заголовочные файлы библиотек в этом случае будут помещены в /usr/local/include.

В ряде дистрибутивов (в Ubuntu) загрузчик не настроен просматривать каталог /usr/local/lib, соответственно, если пользователь установит библиотеку из исходников, система её не увидит. Сиё авторами дистрибутива сделано специально, что бы приучить пользователя устанавливать программное обеспечение только через систему управления пакетами. Как поступить в данном случае будет рассказано ниже.

В действительности, для упрощения и ускорения процесса поиска файлов библиотек, загрузчик не просматривает при каждом обращении указанные выше каталоги, а пользуется базой данных, хранящейся в файле /etc/ld.so.cache (кэшем библиотек). Здесь собрана информация о том, где в системе находится соответствующий данному soname файл библиотеки. Загрузчик, получив список необходимых конкретному приложению библиотек (список soname библиотек, заданных в исполняемом файле программы), посредством /etc/ld.so.cache определяет путь к файлу каждой требуемой библиотеки и загружает её в память. Дополнительно, загрузчик может просмотреть каталоги перечисленные в системных переменных LD_LIBRARY_PATH, LIBRARY_PATH и в поле RPATH исполняемого файла (смотри выше).

Для управления и поддержания в актуальном состоянии кэша библиотек используется утилита ldconfig. Если запустить ldconfig без каких-либо опций, программа просмотрит каталоги заданные в командной строке, доверенные каталоги /lib и /usr/lib, каталоги перечисленные в файле /etc/ld.so.conf. Для каждого файла библиотеки, оказавшегося в указанных каталогах, будет считано soname, создана основанная на soname символическая ссылка, обновлена информация в /etc/ld.so.cache.

Убедимся в сказанном:



$ ls
hello.h libhello.so libhello.so.2.4.0.5 main.c
$ gcc -Wall -o main main.c -L. -lhello
$ ./main
./main: error while loading shared libraries: libhello.so.2: cannot open shared object file: No such file or directory
$ sudo ldconfig /полный/путь/к/катаогу/c/примером
$ ls
hello.h libhello.so libhello.so.2 libhello.so.2.4.0.5 main main.c
$ ./main
First function...
Second function...
Main function...
$ sudo ldconfig
$ ./main
./main: error while loading shared libraries: libhello.so.2: cannot open shared object file: No such file or directory

Первым вызовом ldconfig мы внесли в кэш нашу библиотеку, вторым вызовом исключили. Обратите внимание, что при компиляции main была опущена опция -Wl,-rpath,., в результате загрузчик проводил поиск требуемых библиотек только в кэше.

Теперь должно быть понятно как поступить если после установки библиотеки из исходников система её не видит. Прежде всего необходимо внести в файл /etc/ld.so.conf полный путь к каталогу с файлами библиотеки (по умолчанию /usr/local/lib). Формат /etc/ld.so.conf - файл содержит список разделённых двоеточием, пробелом, табуляцией или символом новой строки, каталогов, в которых производится поиск библиотек. После чего вызвать ldconfig без каких-либо опций, но с правами суперпользователя. Всё должно заработать.

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

$ ls
hello.h libhello.a libhello.so libhello.so.2 libhello.so.2.4.0.5 main.c
$ gcc -Wall -c main.c
$ gcc -o main main.o -L. -lhello -Wl,-rpath,.
$ ldd main
linux-vdso.so.1 => (0x00007fffe1bb0000)
libhello.so.2 => ./libhello.so.2 (0x00007fd50370b000)
libc.so.6 => /lib/libc.so.6 (0x00007fd50336c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd50390f000)
$ du -h main
12K main

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

Существует опция gcc -static - указание линковщику использовать только статические версии всех необходимых приложению библиотек:

$ gcc -static -o main main.o -L. -lhello
$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.15, not stripped
$ ldd main
не является динамическим исполняемым файлом
$ du -h main
728K main

Размер исполняемого файла в 60 раз больше, чем в предыдущем примере - в файл включены стандартные библиотеки языка C. Теперь наше приложение можно смело переносить из каталога в каталог и даже на другие машины, код библиотеки hello внутри файла, программа полностью автономна.

Как же быть если необходимо осуществить статическую линковку только части использованных библиотек? Возможный вариант решения - сделать имя статической версии библиотеки отличным от имени разделяемой, а при компиляции приложения указывать какую версию мы хотим использовать на этот раз:

$ mv libhello.a libhello_s.a
$ gcc -o main main.o -L. -lhello_s
$ ldd main
linux-vdso.so.1 => (0x00007fff021f5000)
libc.so.6 => /lib/libc.so.6 (0x00007fd0d0803000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd0d0ba4000)
$ du -h main
12K main

Так как размер кода библиотеки libhello ничтожен,

$ du -h libhello_s.a
4,0K libhello.a

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

http://pyviy.blogspot.ru/2010/12/gcc.html

КОМАНДНАЯ СТРОКА. СПРАВОЧНИК АДМИНИСТРАТОРА

Как сделать простой веб-сайт за один час

$
0
0


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


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



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



1. Идёте на namecheap.comи регистрируете домен. Этот шаг только в том случае, если нужно собственное доменное имя.



2. Создаёте аккаунт Githubи скачиваете Git, если это ещё не сделано.



3. Создаёте директорию для размещения веб-сайта и перемещатесь туда командой cd: это команды mkdir my-site && cd my-site. Все будущие команды предполагают, что вы внутри рабочей директории.



4. Делаем новый репозиторий Githubдля сайта под названием yourusername.github.io. Например, я зарегистрирован под именем smilli, так что мой репозиторий называется smilli.github.io.



5. В рабочей директории запускаем git initи git remote add origin github.com/username/username.github.io.git, где вместо ‘username’ указываем свой имя пользователя.



6. Создаём файл ‘index.html’ в папке с сайтом с HTML-кодом главной страницы. Здесь необязательно тратить много времени, он может быть весьма лаконичным.



<html><head><title>YOUR SITE TITLE</title><--Addsomestyletoyoursite, seehttp://getbootstrap.comfordetails--><linkrel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"></head><body><h1>YOUR SITE TITLE</h1><p>Your text blahblahbhalbha</p><p>Another paragraph!  Maybe more text!</p></body></html>


7. Пишем в коде главной страницы любой текст. Изменения отображаются локально командой python -m SimpleHTTPServer 8000и набором адреса localhost:8000 в браузере.



8. Теперь запускаем следующие команды:

git add .
git commit -m"Initial commit"
git push -u origin master


9. Идём на yourusername.github.io. Здесь вы должны увидеть свой сайт! Поздравляю, вы что-то опубликовали в онлайне.



10. Если хотите собственное доменное имя, создаёте файл ‘CNAME’ (всё прописными буквами). Туда добавляете одну строчку ‘'yourdomainname.com' (без http или www). См. подробности конфигурации CNAME здесь.



11. Как и раньше, отправляем все изменения на Github.



git add .
git commit -m "Add CNAME"
git push


12. Теперь авторизуетесь на namecheap.comи щёлкаете по доменному имени, которое нужно, в списке своих доменов. Список будет примерно таким:







После выбора домена, появится ссылка «All Host Records» в левой панели во вкладке «Host Management». Нажмите на неё. Теперь вы увидите настройки по умолчанию, которые Namecheap указал для вашего сайта.







Измените настройки следующим образом (заменив ‘username’ на своё имя пользователя, конечно).







13. После вступления в действие изменений в DNS вы сможете увидеть свой сайт на своём домене! Поздравляю. :)

https://geektimes.ru/post/248048/
https://habrahabr.ru/post/254393/
http://klen.github.io/github-blog.html
http://isizov.ru/github-kak-hosting-dlya-sajtov/
https://modx.pro/howto/3062-how-to-start-to-participate-in-open-source/
http://sphinx-ru.readthedocs.org/ru/latest/rtd-gh.html
http://git-scm.com/book/ru/v1

Искусство командной строки

Бесплатный VPN сервер, клиент, и тд

$
0
0


Бесплатный VPN от Amazon
https://habrahabr.ru/post/107631/
https://xakep.ru/2011/01/10/55552/
Создаём VPN-сервер в Amazon EC2
http://www.3dnews.ru/608198
настраиваем VPN, работающий через Amazon EC2
https://dxdt.ru/2012/08/06/5063/
Создание аккаунта (регистрация) на AWS Amazon
http://www.ubuntomania.ru/servery/amazon/444-sozdanie-akkaunta-registracziya-na-aws-amazon.html
Установка и запуск виртуального сервера Ubuntu Server на Amazon AWS (EC2)
http://www.ubuntomania.ru/servery/amazon.html
http://www.ubuntomania.ru/servery/amazon/454-ustanovka-i-zapusk-servera-na-amazon-aws.html
Как я умудрился за 1 день задолжать Amazon 12000$
https://geektimes.ru/post/247794/
Тонкий клиент HP в качестве домашнего роутера и файл-сервера (настройки)
https://habrahabr.ru/post/273547/
Установка VNC сервера, и настройка его работы поверх SSH
https://habrahabr.ru/company/ua-hosting/blog/273201/
https://habrahabr.ru/post/141483/Бесплатный VPN от Comodo
https://habrahabr.ru/post/208782/ SoftEther VPN

Компиляция Windows программы в Ubuntu Linux

$
0
0


Было необходимо срочно сделать маленькую программу под Windows, открывающую файл index.htmlв браузере.

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

В итоге решил собрать эту программу в линуксе. Погуглив, узнал что есть такая программа, как «mingw32», ей то и решил воспользоваться. После установки пакета gcc-mingw32, а заодно и wine (для проверки готовой программы), скопилировал программу на си:

start.c:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h> 
int main(int argc, char *argv[])
{
    ShellExecute(NULL, "open", "index.html", NULL, NULL, SW_SHOWNORMAL);
    return 0;
}


Компилируем:

$ i586-mingw32msvc-gcc start.c -o start.exe


Вуаля, файл start.exeготов к использованию в Windows. На всякий случай проверяем:



$ wine start.exe


В браузере открывается наш index.htmlфайл, что и требовалось.

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

Не пришлось бы этого делать, если бы хоть кто-то выложил скомпилированную программу, а не только её исходники. Исправляю эту ситуацию, выкладываю готовый start.exe: start.7z(упаковано в 7-Zip архив)

И ещё, обязательно проверяйте исполняемые файлы на отсутствие вирусов: http://www.kaspersky.ru/scanforvirus


если кому интересно: сделал в Geany на F8 сборка для Linux, на F9 - под Windows. Для этого в параметрах сборки указываем:
скомпилировать: gcc -o "%e""%f" -lm
собрать: i586-mingw32msvc-gcc "%f" -o "%e".exe

http://ibnteo.klava.org/2011/04-07-linux
http://uzverss.livejournal.com/38925.html
http://blog.golovin.in/portable-mingw-and-msys/

Взлом Wifi WPA/WPA2 паролей с использованием Reaver

$
0
0


2




Если у вас какие-либо проблемы с беспроводными устройствами, то следует ознакомиться со статьёй «Лучшие совместимые с Kali Linux USB Wi-Fi адаптеры.


Обзор Reaver



Reaver предназначен для подборки пина WPS (Wifi Protected Setup) методом перебора. Конечной целью является расшифровка пароля WPA/WPA2. Reaver создан для надёжной и практичной атаки на WPS, он прошёл тестирование на большом количестве точек доступа с разными реализациями WPS. В среднем, Reaver раскрывает пароль WPA/WPA2 в виде простого текста целевой точки доступа (ТД) за 4-10 часов, в зависимости от ТД. На практике, ему обычно нужна половина этого времени на предположение пина WPS и разгадки пароля.



Т.к. оригинальная версия Reaver не обновлялась с января 2012 года, то был сделан форк. Сайт форка — https://code.google.com/p/reaver-wps-fork/. Последние изменения в форке датируются январём 2014 года.



Жизнь не стоит на месте. И совсем недавно (в апреле 2015 года) была официально выпущена модифицированная версия форка Reaver. Сайт этой модификации — https://github.com/t6x/reaver-wps-fork-t6x. Главное её отличие в том, что она может использовать атаку Pixie Dust для нахождения верного пина WPS. Эта атака применима ко многим точкам доступа Ralink, Broadcom и Realtek. Атака, используемая для этой версии, разработана Wiire.



Запускается модифицированная версия Reaver точно также, как и форк. О новых ключах форка и какие нововведения он нам несёт будет рассказано ниже.



Перед тем, как мы начнём, заинтересованных в теме анализа и взлома Wi-Fi сетей перенаправляю также к статье «Взлом Wi-Fi пароля (WPA/WPA2), используя pyrit и cowpatty в Kali Linux». Там используется метод перехвата рукопожатия (программой Wifite) и предлагается очень быстрый метод расшифровки пароля. Скорость достигается за счёт применения техники значительного ускорения перебора паролей.


Основные векторы взлома Wi-Fi сетей:


  • перехват рукопожатий (хендшейков) и последующий их брутфорсинг

  • подбор пина на ТД с включённым WPS.

Данная статья посвящена второму способу.



Если вы перехватили рукопожатия и вы хотите применить атаку брут-форсинг, то у меня есть ещё пара ссылок для вас. Во-первых, статья, которую я рекомендовал чуть выше, рассказывает, как произвести быстрый перебор по словарю. А в статье «Взлом паролей WPA2/WPA с помощью Hashcat в Kali Linux (атака перебором Wi-Fi паролей по маске)», как следует из её названия, рассказано о переборе по маске. Это значительно ускорит процесс, если нам известны некоторые символы из пароля, либо мы знаем правила, в соответствии с которыми этот пароль генерировался. Вообще Hashcat мощная программа, которая может взламывать не только пароли Wifi WPA/WPA2, но и пароли MD5, phpBB, MySQL, SHA1 и многие другие.


Суть метода атаки Reaver — подбор WPS



Главное, что нам нужно от атакуемой точки доступа, это включённость на ней WPS. В случае правильного введения пина, ТД сама предоставит нам необходимые данные для аутентификации (в т.ч. WPA PSK).



Как уже было сказано, нужно ввести правильный пин. Думаю, все уже догадались, что Reaver занимается тем, что перебирает пины, пока не найдёт верный. Об этом пине известно следующее: это восьмизначное число. Вводить его можно в любое время — каких-либо действий со стороны владельца ТД не требуется. Нам не нужна никакая больше информация: ни о настройках ТД, ни о шифровании или конфигурации. Для восьмизначных чисел возможно 10^8 (100,000,000) вариантов. Но последняя цифра не является случайно, она рассчитывается по алгоритму, т. е. говоря простым языком, последнюю цифру мы всегда знаем, и количество возможных вариантов сокращается до 10^7 (10,000,000).



Ну и будто бы специально, чтобы нам было проще брутфорсить, пин делится на две половины, и каждая из этих половин проверяется индивидуально. Это означает, что для первой половины 10^4 (10,000) возможных вариантов, а для второй — всего 10^3 (1,000), т. к. последняя цифра не является случайной.



Reaver подбирает первую половину пина, а потом вторую. Общее число возможных вариантов, как мы только что посчитали, равняется 11,000. Скорость, с которой Reaver тестирует номера пинов полностью зависит от скорости с которой ТД может обрабатывать запросы. Некоторые достаточно быстрые — можно тестировать по одному пину в секунду, другие — медленнее, они позволяют вводить только один пин в 10 секунд.


Установка Reaver


Установите Kali Linux, там уже всё встроено. (Reaver, libpcap и libsqlite3).


Использование Reaver


Начинаем вводом команды


1
airmon-ng


1



И смотрим на вывод, точнее нас интересует только интерфейс. Он называется wlan0. Теперь набираем команду airmon-ng start <имя_интерфейса>


У меня так:


1
airmon-ng start wlan0


Для Reaver нужна следующая информация: имя интерфейса и BSSID целевой ТД. Узнать, какие ТД находяться в радиусе доступности, а также их BSSID можно так:


1
airodump-ng --wps wlan0mon


2



Например, из этого списка меня заинтересовал ТД Kitty, её BSSID — 4C:72:B9:FE:B8:0C.



Вся необходима информация для запуска Reaver'а у меня есть. Останавливаем airodump-ng и запускаем Ривер.


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C


Канал и SSID (при условии, что SSID не замаскирована) целевой ТД будет автоматически идентифицирована Reaver'ом, если они не заданы явным образом в командной строке:

1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -c 4 -e Kitty


По умолчанию, если ТД переключает каналы, Reaver также будет соответственно переключать каналы. Тем не менее, эту функцию можно отключить, зафиксировав канал интерфейса:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --fixed


Таймаут по умолчанию равен 5 секундам. Если нужно, этот период таймаута можно задать вручную (минимальный период таймаута — 1 секунда).


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -t 2


Дефолтный период между попытками пина — 1 секунда. Эта величина может быть увеличена или уменьшена до любого не отрицательного целого числа. Величина ноль означает без задержки:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -d 0


Некоторые ТД временно блокирует их WPS состояние, обычно на 5 минут или меньше, когда выявлена «подозрительная» активность. По умолчанию, когда выявлен заблокированное состояние, Reaver будет проверять состояние каждый 315 секунд (5 минут и 15 секунд) и не будет продолжать брут-форсить, пока WPS состояние не разблокируется. Эта проверка может быть увеличена или уменьшена до любой не отрицательной целой величины:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --lock-delay=250


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


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -vv


Дефолтный период получения сообщений ответа M5 и M7 WPS — 0.1 секунды. Если нужно, этот период таймаута может быть задан автоматически (максимальный период таймаута — 1 секунда):


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -T .5


Некоторые убогие реализации WPS разрывают соединение, если введён неверный пин, вместо того, чтобы отвечать сообщением NACK, как этого требует спецификация. В расчёте на это, если достигнут таймаут M5/M7, это лечится также установлением NACK по умолчанию. Тем не менее, если известно, что целевая ТД отправляет NACK'и (большинство делают), эта функция может быть отключена для улучшения совместимости. Обычно эта опция не используется, поскольку Reaver автоматически определяет, отправляет ли ТД надлежащие ответы с NACK'и или нет:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --nack


Хотя большинство ТД не заботятся об отправки им сообщения EAP FAIL для закрытия сессии WPS, иногда это необходимо. По умолчанию, эта функция отключена, но она может быть задействована для тех ТД, которым это нужно:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --eap-terminate


Когда случаются 10 последовательных неожиданных ошибок WPS, будет отображено сообщение предупреждения. Поскольку это может быть знаком того, что ТД ограничивает скорость попыток пина или просто перегружена, то на этот случай может быть задан период сна, который программа будет бездействовать при появлении этого сообщения предупреждения:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --fail-wait=360

Ускоряем атаку



По умолчанию, Reaver имеет задержку в 1 секунду между попытками пина. Вы можете отключить эту задержку добавив «-d 0» к командной строке, но некоторые ТД не любят этого:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -d 0


Другая опция, которая может ускорить атаку, это –dh-small. Эта опция инструктирует Reaver использовать маленькие секретные номера Диффи-Хеллмана, чтобы уменьшить вычислительную нагрузку на целевую ТД:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C --dh-small

Reaver, атака Pixiewps и ключ -K 1



Не так давно открытая атака Pixiewps позволяет взламывать некоторые модели роутеров за считанные секунды. Модификация форка Reaver — t6x — для использования атаки Pixie Dust включена в Kali Linux. При этом она заменяет оригинальную версию. Т.е. запускать её нужно точно также, как и устаревший Reaver. Единственным её отличием является поддержка атаки Pixiewps и нескольких новых ключей. Одним из этих ключей является -K 1. Если задать этот ключ, то Reaver попытается осуществить в отношении выбранной ТД атаку Pixiewps. Т.е. теперь команда будет выглядеть так:


1
reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -K 1


Этой модификации посвящена отдельная статья «Модификация форка Reaver — t6x — для использования атаки Pixie Dust».


Ту статью стоит прочитать хотя бы по следующим причинам:


  • там дан перевод всей справки Reaver по всем ключам;

  • там рассказано о трёх новых ключах: -K // —pixie-dust в reaver; -H // —pixiedust-log в reaver; -P // —pixiedust-loop в reaver

Подмена MAC



В некоторых случаях вам может хотеть/нужно подменить ваш MAC адрес. Reaver поддерживает подмену MAC мадрес с опцией –mac, но вам нужно убедиться, что MAC адрес корректно подменён, т. к. есть нюансы.



Изменение MAC адреса виртуального интерфейса режима монитора (теперь называемого wlan0mon) НЕ БУДЕТ РАБОТАТЬ. Вы должны изменить MAC адрес физического интерфейса вашей беспроводной карты. Например:


1
2
3
4
5
# ifconfig wlan0 down
# ifconfig wlan0 hw ether 04:DE:AD:BE:EF:45
# ifconfig wlan0 up
# airmon-ng start wlan0
# reaver -i wlan0mon -b 4C:72:B9:FE:B8:0C -vv --mac=04:DE:AD:BE:EF:45


https://webware.biz/?p=3847
https://habrahabr.ru/company/xakep/blog/143834/
https://trashbox.ru/topics/56221/kali-linux-vzlom-wi-fi-po-protokolu-wps
http://4pda.ru/forum/index.php?showtopic=422256
http://blackdiver.net/it/linux/3032
http://rootsector.blogspot.ru/2014/09/reaver.html
http://tt.erinome.net/2013/03/447


Полезные команды Linux, о которых вы не знали

$
0
0

Сайт commandlinefu.comсоздан для сбора полезных команд Linux-терминала, которые хочется использоваться снова и снова. О многих вы могли даже ничего не знать, но увидев наверняка подумаете: «Круто! А что, так можно было?»

sudo !!— запустить последнюю команду от имени рута. Полезно, если вы забыли добавить sudo в начале строки.

python -m SimpleHTTPServer— сделать доступной текущую директорию по адресу http://$HOSTNAME:8000/.

^foo^bar— выполнить предыдущую команду, но с заменой. Например, попробуйте запустить echo "tprogezr", а затем ^z.

ctrl-x e— зажать Ctrl и не отпуская x, затем e. Запускает редактор, чтобы можно было удобно составить большую сложную команду.

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

'ALT+.'или ' .'— поместить аргумент последней команды в консоль.

reset— восстановить терминал после вывода в него сырых бинарных данных или других ошибок формирования текста на экране.

mount | column -t— информация о текущих смонтированных файловых системах с удобным оформлением по столбцам.

echo "ls -l" | at midnight— выполнить команду в указанное время.

curl ifconfig.me— получить свой внешний IP.

ssh -N -L2001:localhost:80 somemachine — создать туннель от 80 порта на удалённой машине до 2001 на локальной.

man ascii— быстрый доступ к таблице ASCII.

dd if=/dev/dsp | ssh -c arcfour -C username@host dd of=/dev/dsp— перенаправить звук с вашего микрофона на колонки на удалённой машине.

arecord -f dat | ssh -C user@host aplay -f dat— более современный вариант предыдущей команды.

ctrl+u [...] ctrl+y— запомнить текущую набираемую команду, а затем восстановить. Например, если в процессе набора команды вы что-то забыли, а затем хотите вернуться и продолжить.

wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com— выкачать весь сайт.

curl -u user:pass -d status="Tweeting from the shell"http://twitter.com/statuses/update.xml— сделать твит через curl.

(cd /tmp && ls)— перейти к директории, выполнить там команду, вернуться к предыдущей директории.

Больше команд можно найти на этом сайте.


https://tproger.ru/articles/cool-linux-commands/

книги "Инструменты Linux, Модули ядра Linux"

$
0
0


Оригинал взят у oleg_tsiliuricв книга "Инструменты Linux"
Выложена для свободного доступа редакция книги "Инструменты Linux" (главным образом, для программистов). К книге выложен архив примеров кода. Все ссылки здесь: http://mylinuxprog.blogspot.com/2012/11/linux_25.html

Обсуждение книги (замеченные ошибки, пожелания к расширению и др.) на форуме: http://rus-linux.net/forum/viewtopic.php?f=25&t=1984 


Выложена для свободного доступа свежая редакция книги "Модули ядра Linux" (о программировании драйверов для системы Linux). К книге выложен архив примеров кода. Все ссылки здесь: http://mylinuxprog.blogspot.com/2012/11/linux_24.html

видеоплеер Parole не показывает видео

$
0
0


видеоплеер Parole воспроизводит лишь звук, а Mplayer выводит сообщение:
Ошибка драйвера GStreamer
Could not initialise Xv output


лечится командой:
parole --xv false

http://forum.ubuntu.ru/index.php?topic=248302.0

mplayer в консоли

$
0
0


mplayer -vo fbdev2 -zoom -x 1024 -y 768 -fs Видео/In\ taberna\ quando\ sumus\ by\ Arany\ Zoltán\ -\ YouTube.flv

Перемещение по фильму
Клавиатурные клавиши ← и → позволяют передвинуться назад/вперёд по фильму на 10 секунд
Кнопки ↑ и ↓ поможет передвинуться назад/вперёд на 1 минуту
кнопки PgUp и PgDwn передвинуться назад/вперёд на 10 минут
Следует так же сказать, что кнопки [ и ] замедляют и ускоряют воспроизведение видео вместе со звуком. Это довольно полезная опция, особенно когда смотришь видеолекции, где выступающий говорит слишком быстро.

Изменить яркость, контраст, или насыщенность
Кнопки 1 и 2 понижают/повышают контраст
Кнопки 3 и 4 понижают/повышают яркость
Кнопки 5 и 6 понижают/повышают оттенки
Кнопки 7 и 8 понижают/повышают насыщенность
Не все эти операции поддерживаются различными методами видеовывода.

Синхронизация видео и звука
Используя клавиши + и - можно компенсировать назад/вперёд десинхронизацию на 0.1 секунд. Можно указать параметр -autosync 0:
mplayer -autosync 0 video.avi
для запрета автоматической синхронизации, или прописать параметр -autosync 0

Компенсация соотношения сторон (неправильный aspect ratio)
В консоли запускаем mplayer c параметром -monitoraspect X:Y где вместо X и Y подбираем правильные соотношения экспериментально. Пример:
mplayer -monitoraspect 4:4 1984.mpg
или
mplayer -monitoraspect 1.5:1.05 Matrix2.avi

Если нужно сделать так, чтобы видео воспроизводилось в цикле, пишем команду:
mplayer -loop 0 megavideo.avi

Бесценная шпаргалка по управляющим клавишам для Mplayer:



http://mydebianblog.blogspot.ru/2012/08/mplayer.html

UTF в консоли FreeBSD

$
0
0




Добавляем в файл /boot/loader.conf

kern.vty=vt

Добавляем в файл /etc/rc.conf способ переключения раскладки в консоли клавишами CTRL+SHIFT

keymap="ru.win"

Проверяем тип консоли в файле /etc/ttys, должно быть xterm

ttyv0 "/usr/libexec/getty Pc" xterm on secure

Редактируем класс «russian» в файле /etc/login.conf, должно получиться следующее:
russian|Russian Users Accounts:\
       :charset=UTF-8:\
       :lang=ru_RU.UTF-8:\
       :tc=default:

Обновляем /etc/login.conf.db командой:

cap_mkdb /etc/login.conf

Локализуем shell, я использую tcsh, для него редактируем файл ~/.cshrc, добавив в него две следующие строки:

setenv LANG ru_RU.UTF-8
setenv MM_CHARSET UTF-8

Пользователю необходимо прописать класс russian, командой:

pw user mod user_name -L russian

Где user_name — имя пользователя

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

pw useradd user_name -L russian

Вот и все, перезайдите в shell, для локализации терминала, консоль русифицируется после перезагрузки системы.

http://blog.marvins.ru/administrirovanie/utf-8-v-konsoli-i-terminale-freebsd-10-2.html
http://www.linux.org.ru/forum/general/11209349/page1?lastmod=1423946536868#comment-11321679
http://unix1.jinr.ru/~lavr/vt/vtcons.html
http://pascal.tsu.ru/unix/syscons/russian.html
http://www.ntwk.ru/docs/freebsd/handbook/book.html
https://www.freebsd.org/cgi/man.cgi?query=vt&sektion=4

Переводите любой выбранный текст с помощью комбинации клавиш и оповещений

$
0
0


1. Чтобы иметь возможность использовать скрипт, для начала установите библиотеки libnotify-bin (для того, чтобы скрипт мог отправлять оповещения рабочего стола), wget (для получения перевода фразы через Google) и xsel (для получения текущего выбранного текста). В Ubuntu, Linux Mint и прочих дистрибутивах вы можете установить их с помощью следующей команды в вашем терминале (чтобы открыть его, используйте комбинацию клавиш Ctrl+Alt+T):

sudo apt-get install libnotify-bin wget xsel

2. Затем скопируйте код скрипта ниже:

вариант 1
notitrans1.sh


вариант 2
нужно установить zenity

sudo apt-get install

notitrans2.sh
Отображение перевода через Zenity (который поддерживает копирование текста) вместо использования оповещений рабочего стола:


вариант 3
Отображение перевода в виде оповещения рабочего стола и автоматическое копирование перевода в буфер обмена, необходим установленный xclip:

sudo apt-get install xclip

notitrans3.sh


В скрипте выше замените "tl=ru"на язык, на который вы хотите переводить выбранные тексты,
например, "tl=en"для английского языка, "tl=fr"для французского и так далее.

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

chmod +x ~/notitrans* #(выбранный_вариант)

3. Поместите скрипт в ваш $PATH – например, чтобы поместить скрипт в /usr/local/bin/, используйте следующую команду:

sudo mv ~/notitrans /usr/local/bin/

либо создайте в домашнем какталоге папку bin (/home/ваш_аккаунт/bin)
и добавьте эту папку в $PATH например так:

sudo nano /etc/environment

добавить

/home/user/bin

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

http://myubuntu.ru/programmy/perevodite-lyuboj-vybrannyj-tekst-s-pomoshchyu-kombinatsii-klavish-i-opoveshchenij

проверь, какой ты сисадмин


Raspberry PI Python

$
0
0

Подборка журналов Хакер начала 2000-х :)

Установка Node.js с помощью NVM

$
0
0

Для начала нужно получить из репозитория Ubuntu программы, которые позволят построить пакеты с исходными кодами. Nvm будет использовать эти инструменты для сборки необходимых компонентов:


sudo apt-get update

sudo apt-get install build-essential libssl-dev



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


curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash


Это скачает скрипт и запустит его. Программа будет установлена в подкаталог домашнего каталога в ~/.nvm; кроме того, в файл ~/.profile будут внесены необходимые строки.


Чтобы получить доступ к функциям nvm, нужно выйти из системы и войти снова, или же запустить команду source на файл ~/.profile, чтобы сообщить текущей сессии о внесенных изменениях.


source ~/.profile


Теперь, когда nvm установлен, можно перейти к установке изолированных версий Node.js.


Чтобы узнать, какие версии Node.js доступны, наберите:


nvm ls-remote

. . .

v0.11.6

v0.11.7

v0.11.8

v0.11.9

v0.11.10

v0.11.11

v0.11.12

v0.11.13


Как видите, на данный момент последняя доступная версия — 0.11.13. Ее можно установить, набрав:


nvm install 0.11.13


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


nvm use 0.11.13


При установке Node.js с помощью nvm исполнительный файл называется node. Чтобы узнать, какая версия используется в данный момент, введите:


node -v

v.0.11.13


При наличии нескольких версий Node.js можно просмотреть, какие версии установлены:


nvm ls


Чтобы сделать одну из версий версией по умолчанию, введите:


nvm alias default 0.11.13


Данная версия будет автоматически запущена в каждой новой сессии. На нее можно сослаться по псевдониму:


nvm use default


Каждая версия Node.js будет отслеживать свои пакеты и давать npm возможность управлять ними.


npm может установить пакеты в каталог проекта Node.js  (./node_modules) с помощью обычного формата:


npm install express


Чтобы установить Node.js глобально (т.е., доступно для других проектов, которые используют эту версию Node.js), внесите флаг -g:


npm install -g express


Это установит пакеты в


~/.nvm/node_version/lib/node_modules/package_name


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


npm link express


Чтобы узнать о доступных опциях nvm больше, наберите:


nvm help



http://www.8host.com/blog/ustanovka-node-js-na-ubuntu-14-04/
https://www.digitalocean.com/community/tutorials/node-js-ubuntu-14-04-ru
https://github.com/creationix/nvm
http://uzverss.livejournal.com/51536.html
http://uzverss.livejournal.com/tag/nodejs

JavaScript подборка

$
0
0




Сайты


http://javascript.ru/
http://nodebeginner.ru/
https://nodejs.org/
https://www.npmjs.com/
https://github.com/creationix/nvm
http://sweetjs.org/
http://www.espruino.com/
https://os.js.org/
http://node-os.com/

Статьи


https://habrahabr.ru/post/281879/
https://habrahabr.ru/post/133363/
https://habrahabr.ru/post/206678/
https://habrahabr.ru/post/200866/
https://habrahabr.ru/hub/javascript/
https://habrahabr.ru/hub/nodejs/
http://www.8host.com/blog/ustanovka-node-js-na-ubuntu-14-04/
https://www.digitalocean.com/community/tutorials/node-js-ubuntu-14-04-ru
http://uzverss.livejournal.com/62165.html
http://uzverss.livejournal.com/51536.html
http://uzverss.livejournal.com/tag/javascript
http://arduino-diy.com/arduino-udalennoye-upravleniye-motorom-postoyannogo-Node-js
http://blog.denivip.ru/index.php/2012/11/разработка-высокопроизводительных-с/
http://blog.denivip.ru/index.php/2012/12/подводные-камни-при-разработке-крупн/
http://webtackles.ru/javascript/js-modules-beginners-guide/
http://sources.ru/jscript/index.html
http://www.cyberguru.ru/web/html/javascript-samples.html

Самоучители


http://learn.javascript.ru/
http://bonsaiden.github.io/JavaScript-Garden/ru/
http://s-engineer.ru/struktura-i-sintaksis-javascript-vyzhimka/
http://webmaster.ee/javascript/js.html
http://nodeguide.ru/doc/
http://www.wisdomweb.ru/JS/javascript-first.php
http://ilnurgi1.ru/docs/js/index.html

Блоги


https://vk.com/js_hub
https://vk.com/html_css_php_help
https://vk.com/club12188866
https://vk.com/nodenews
https://vk.com/js_kitchen
https://vk.com/hero.develop
https://vk.com/ecmas
https://vk.com/webdiveorg
https://vk.com/jsrussia

Подборки


https://vk.com/page-54530371_48792013
https://vk.com/page-54530371_49270641

Видео


https://www.youtube.com/playlist?list=PL363QX7S8MfSxcHzvkNEqMYbOyhLeWwem
https://www.youtube.com/playlist?list=PLDyvV36pndZFWfEQpNixIHVvp191Hb3Gg

Консоль


http://plnkr.co/edit/?p=preview
https://repl.it/languages/javascript
http://www.tutorialspoint.com/codingground.htm
http://rextester.com/l/js_online_compiler
https://jsconsole.com/
http://math.chapman.edu/~jipsen/js/

Разное


https://lurkmirror.ml/JavaScript
http://www.govnokod.ru/javascript

обновление FreeBSD

$
0
0



https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi?az=post&om=107420&forum=vsluhforumID3&omm=235

Viewing all 433 articles
Browse latest View live