четверг, 22 марта 2012 г.

BASH errors

1. for i in `ls *.mp3`


Одна из наиболее часто встречающихся ошибок в bash-скриптах — это циклы типа такого:

for i in `ls *.mp3`; do     
some command $i          

done


Это не сработает, если в названии одного из файлов присутствуют пробелы, т.к. результат подстановки команды ls *.mp3 подвергается разбиению на слова. Предположим, что у нас в текущей директории есть файл 01 - Don't Eat the Yellow Snow.mp3. Цикл for пройдётся по каждому слову из названия файла и $iпримет значения: "01", "-", "Don't", "Eat", "the", "Yellow", "Snow.mp3".

Заключить всю команду в кавычки тоже не получится:

for i in "`ls *.mp3`"; do   # Неверно!     ...


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

На самом деле использование ls совершенно излишне: это внешняя команда, которая просто не нужна в данном случае. Как же тогда правильно? А вот так:

for i in *.mp3; do         # Гораздо лучше, но... 
some command "$i"          # ... см. подвох №2 done


Предоставьте bash'у самому подставлять имена файлов. Такая подстановка не будет приводить к разделению строки на слова. Каждое имя файла, удовлетворяющее шаблону *.mp3, будет рассматриваться как одно слово, и цикл пройдёт по каждому имени файла по одному разу.

Дополнительные сведения можно найти в п. 20 Bash FAQ.

Внимательный читатель должен был заметить кавычки во второй строке вышеприведённого примера. Это плавно подводит нас к подвоху №2.

2. cp $file $target


Что не так в этой команде? Вроде бы ничего особенного, если вы абсолютно точно знаете, что переменные $file и $target не содержат пробелов или подстановочных символов.

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

cp "$file" "$target"


Без двойных кавычек скрипт выполнит команду cp 01 - Don't Eat the Yellow Snow.mp3 /mnt/usb, и вы получите массу ошибок типа cp: cannot stat `01': No such file or directory. Если в значениях переменных$file или $target содержатся символы *, ?, [..] или (..), используемые в шаблонах подстановки имен файлов («wildmats»), то в случае существования файлов, удовлетворяющих шаблону, значения переменных будут преобразованы в имена этих файлов. Двойные кавычки решают эту проблему, если только "$file" не начинается с дефиса -, в этом случае cp думает, что вы пытаетесь указать ему еще одну опцию командной строки.

Один из способов обхода — вставить двойной дефис (--) между командой cp и её аргументами. Двойной дефис сообщит cp, что нужно прекратить поиск опций:

cp -- "$file" "$target"


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

Ещё один способ — убедиться, что названия файлов всегда начинаются с имени каталога (включая ./ для текущего). Например:

for i in ./*.mp3; do     cp "$i" /target     ...


Даже если у нас есть файл, название которого начинается с "-", механизм подстановки шаблонов гарантирует, что переменная будет содержать нечто вроде ./-foo.mp3, что абсолютно безопасно для использования вместе с cp.

3. [ $foo = «bar» ]



В этом примере кавычки расставлены неправильно: в bash нет необходимости заключать строковой литерал в кавычки; но вам обязательно следует закавычить переменную, если вы не уверены, что она не содержит пробелов или знаков подстановки (wildcards).

Этот код ошибочен по двум причинам:

1. Если переменная, используемая в условии [, не существует или пуста, строка

[ $foo = "bar" ]


будет воспринята как

[ = "bar" ]


что вызовет ошибку «unary operator expected». (Оператор "=" бинарный, а не унарный, поэтому команда [будет в шоке от такого синтаксиса)
2. Если переменная содержит пробел внутри себя, она будет разбита на разные слова перед тем, как будет обработана командой [:
[ multiple words here = "bar" ]

Даже если лично вам кажется, что это нормально, такой синтаксис является ошибочным.

Правильно будет так:

[ "$foo" = bar ]       # уже близко!


Но этот вариант не будет работать, если $foo начинается с -.

В bash для решения этой проблемы может быть использовано ключевое слово [[, которое включает в себя и значительно расширяет старую команду test (также известную как [)

[[ $foo = bar ]]       # правильно!


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

Возможно, вы видели код типа такого:

[ x"$foo" = xbar ]    # тоже правильно!


Хак x"$foo" требуется в коде, который должен работать в шеллах, не поддерживающих [[, потому что если$foo начинается с -, команда [ будет дезориентирована.

Если одна из частей выражения — константа, можно сделать так:
[ bar = "$foo" ]      # так тоже правильно!


Команду [ не волнует, что выражение справа от знака "=" начинается с -. Она просто использует это выражение, как строку. Только левая часть требует такого пристального внимания.

4. cd `dirname "$f"`



Пока что мы в основном говорим об одном и том же. Точно так же, как и с раскрытием значений переменных, результат подстановки команды подвергается разбиению на слова и раскрытию имен файлов (pathname expansion). Поэтому мы должны заключить команду в кавычки:

cd "`dirname "$f"`"


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

Другими словами, парсер рассматривает обратные кавычки (`) как уровень вложенности, и кавычки внутри него отделены от внешних.

Такого же эффекта можно достичь, используя более предпочтительный синтаксис $():

cd "$(dirname "$f")"


Кавычки внутри $() сгруппированы.

5. [ "$foo" = bar && "$bar" = foo ]



Нельзя использовать && внутри «старой» команды test или её эквивалента [. Парсер bash'а видит && вне скобок и разбивает вашу команду на две, перед и после &&. Лучше используйте один из вариантов:

[ bar = "$foo" -a foo = "$bar" ]       # Правильно! [ bar = "$foo" ] && [ foo = "$bar" ]   # Тоже правильно! [[ $foo = bar && $bar = foo ]]         # Тоже правильно!


Обратите внимание, что мы поменяли местами константу и переменную внутри [ — по причинам, рассмотренным в предыдущем пункте.

То же самое относится и к ||. Используйте [[, или -o, или две команды [.

6. [[ $foo > 7 ]]


Если оператор > используется внутри [[ ]], он рассматривается как оператор сравнения строк, а не чисел. В некоторых случаях это может сработать, а может и не сработать (и это произойдёт как раз тогда, когда вы меньше всего будете этого ожидать). Если > находится внутри [ ], всё ещё хуже: в данном случае это перенаправление вывода из файлового дескриптора с указанным номером. В текущем каталоге появится пустой файл с названием 7, и команда test завершится с успехом, если только переменная $fooне пуста.

Поэтому операторы > и < для сравнения чисел внутри [ .. ] или [[ .. ]] использовать нельзя.

Если вы хотите сравнить два числа, используйте (( )):

((foo > 7))                             # Правильно!


Если вы пишете для Bourne Shell (sh), а не для bash, правильным способом является такой:

[ $foo -gt 7 ]                          # Тоже правильно!


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

Двойные квадратные скобки также поддерживают такой синтаксис:

[[ $foo -gt 7 ]]                        # Тоже правильно!


7. count=0; grep foo bar | while read line; do ((count++)); done; echo «number of lines: $count»


На первый взгляд этот код выглядит нормально. Но на деле переменная $count останется неизменной после выхода из цикла, к большому удивлению bash-разработчика. Почему так происходит?

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

В данном случае цикл for является частью конвейера и выполняется в отдельной подоболочке со своей копией переменной $count, инизиализированной значением переменной $count из родительской оболочки: «0». Когда цикл заканчивается, использованная в цикле копия $count отбрасывается и команда echoпоказывает неизменённое начальное значение $count («0»).

Обойти это можно несколькими способами.

Можно выполнить цикл в своей подоболочке (слегка кривовато, но так проще и понятней и работает в sh):

# POSIX compatible count=0 cat /etc/passwd | (     while read line ; do         count=$((count+1))     done     echo "total number of lines: $count" )


Чтобы полностью избежать создания подоболочки, используйте перенаправление (в Bourne shell (sh) для перенаправления также создаётся subshell, поэтому будьте внимательны, такой трюк сработает только в bash):

# только для bash! count=0 while read line ; do     count=$(($count+1)) done < /etc/passwd echo "total number of lines: $count"


Предыдущий способ работает только для файлов, но что делать, если нужно построчно обработать вывод команды? Используйте подстановку процессов:
while read LINE; do     echo "-> $LINE" done < <(grep PATH /etc/profile)


Ещё пара интересных способов разрешения проблемы с субшеллами обсуждается в Bash FAQ #24.

8. if [grep foo myfile]



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

Однако такое мнение — ошибка! Открывающая квадратная скобка ([) — это не часть синтаксиса, а команда, являющаяся эквивалентом команды test, лишь за тем исключением, что последним аргументом этой команды должна быть закрывающая скобка ].

Синтаксис if:

if COMMANDS then     COMMANDS elif COMMANDS     # необязательно then     COMMANDS else              # необязательно     COMMANDS fi


Как видите, в синтаксисе if нет никаких [ или [[!

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

if выполняет первый набор команд, и в зависимости от кода возврата последней команды из этого набора определяет, будет ли выполнен блок команд из секции «then» или же выполнение скрипта продолжится дальше.

Если вам необходимо принять решение в зависимости от вывода команды grep, вам не нужно заключать её в круглые, квадратные или фигурные скобки, обратные кавычки или любой другой синтаксический элемент. Просто напишите grep как команду после if:

if grep foo myfile > /dev/null; then     ... fi


Обратите внимание, что мы отбрасываем стандартный вывод grep: нам не нужен результат поиска, мы просто хотим знать, присутствует ли строка в файле. Если grep находит строку, он возвращает 0, и условие выполняется; в противном случае (строка в файле отсутствует) grep возвращает значение, отличное от 0. В GNU grep перенаправление >/dev/null можно заменить опцией -q, которая говорит grep'у, что ничего выводить не нужно.

9. if [bar="$foo"]



Как было объяснено в предыдущем параграфе, [ — это команда. Как и в случае любой другой команды, bash предполагает, что после команды следует пробел, затем первый аргумент, затем снова пробел, и т.д. Поэтому нельзя писать всё подряд без пробелов! Правильно вот так:

if [ bar = "$foo" ]


bar, =, "$foo" (после подстановки, но без разделения на слова) и ] являются аргументами команды [, поэтому между каждой парой аргументов обязательно должен присутствовать пробел, чтобы шелл мог определить, где какой аргумент начинается и заканчивается.

10. if [ [ a = b ] && [ c = d ] ]



Снова та же ошибка. [ — команда, а не синтаксический элемент между if и условием, и тем более не средство группировки. Вы не можете взять синтаксис C и переделать его в синтаксис bash простой заменой круглых скобок на квадратные.

Если вы хотите реализовать сложное условие, вот правильный способ:

if [ a = b ] && [ c = d ]


Заметьте, что здесь у нас две команды после if, объединённые оператором &&. Этот код эквивалентент такой команде:

if test a = b && test c = d


Если первая команда test возвращает значение false (любое ненулевое число), тело условия пропускается. Если она возвращает true, выполняется второе условие; если и оно возвращает true, то выполняется тело условия.

11. cat file | sed s/foo/bar/ > file


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

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

sed 's/foo/bar/g' file > tmpfile && mv tmpfile file

Следующий фрагмент будет работать только при использовании GNU sed 4.x и выше:

sed -i 's/foo/bar/g' file

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

В BSD-версии sed необходимо обязательно указывать расширение, добавляемое к запасной копии файла. Если вы уверены в своем скрипте, можно указать нулевое расширение:

sed -i '' 's/foo/bar/g' file

Также можно воспользоваться perl 5.x, который, возможно, встречается чаще, чем sed 4.x:

perl -pi -e 's/foo/bar/g' file

Различные аспекты задачи массовой замены строк в куче файлов обсуждаются в Bash FAQ #21.

12. echo $foo


Эта относительно невинно выглядящая команда может привести к неприятным последствиям. Поскольку переменная $foo не заключена в кавычки, она будет не только разделена на слова, но и возможно содержащийся в ней шаблон будет преобразован в имена совпадающих с ним файлов. Из-за этого bash-программисты иногда ошибочно думают, что их переменные содержат неверные значения, тогда как с переменными всё в порядке — это команда echo отображает их согласно логике bash, что приводит к недоразумениям.

MSG="Please enter a file name of the form *.zip" echo $MSG

Это сообщение разбивается на слова и все шаблоны, такие, как *.zip, раскрываются. Что подумают пользователи вашего скрипта, когда увидят фразу:

Please enter a file name of the form freenfss.zip lw35nfss.zip

Вот ещё пример:

VAR=*.zip       # VAR содержит звёздочку, точку и слово "zip" echo "$VAR"     # выведет *.zip echo $VAR       # выведет список файлов, чьи имена заканчиваются на .zip

На самом деле, команда echo вообще не может быть использована абсолютно безопасно. Если переменная содержит только два символа "-n", команда echo будет рассматривать их как опцию, а не как данные, которые нужно вывести на печать, и абсолютно ничего не выведет. Единственный надёжный способ напечатать значение переменной — воспользоваться командой printf:
printf "%s\n" "$foo".

13. $foo=bar


Нет, вы не можете создать переменную, поставив "$" в начале её названия. Это не Perl. Достаточно написать:

foo=bar

14. foo = bar


Нет, нельзя оставлять пробелы вокруг "=", присваивая значение переменной. Это не C. Когда вы пишете foo = bar, оболочка разбивает это на три слова, первое из которых, foo, воспринимается как название команды, а оставшиеся два — как её аргументы.

По этой же причине нижеследующие выражения также неправильны:

foo= bar    # НЕПРАВИЛЬНО! foo =bar    # НЕПРАВИЛЬНО! $foo = bar  # АБСОЛЮТНО НЕПРАВИЛЬНО!

foo=bar     # Правильно.

15. echo <
Встроенные документы полезны для внедрения больших блоков текстовых данных в скрипт. Когда интерпретатор встречает подобную конструкцию, он направляет строки вплоть до указанного маркера (в данном случае — EOF) на входной поток команды. К сожалению, echo не принимает данные с STDIN.
# Неправильно: echo <
# Правильно: cat <

16. su -c 'some command'

В Linux этот синтаксис корректен и не вызовет ошибки. Проблема в том, что в некоторых системах (например, FreeBSD или Solaris) аргумент -c команды su имеет совершенно другое назначение. В частности, в FreeBSD ключ -c указывает класс, ограничения которого применяются при выполнении команды, а аргументы шелла должны указываться после имени целевого пользователя. Если имя пользователя отсутствует, опция -c будет относиться к команде su, а не к новому шеллу. Поэтому рекомендуется всегда указывать имя целевого пользователя, вне зависимости от системы (кто знает, на каких платформах будут выполняться ваши скрипты...):
su root -c 'some command' # Правильно.

17. cd /foo; bar

Если не проверить результат выполнения cd, в случае ошибки команда bar может выполниться не в том каталоге, где предполагал разработчик. Это может привести к катастрофе, если bar содержит что-то вроде rm *. Поэтому всегда нужно проверять код возврата команды «cd». Простейший способ:
cd /foo && bar
Если за cd следует больше одной команды, можно написать так:
cd /foo || exit 1 bar baz bat ... # Много команд.
cd сообщит об ошибке смены каталога сообщением в stderr вида bash: cd: /foo: No such file or directory. Если вы хотите вывести своё сообщение об ошибке в stdout, следует использовать группировку команд:
cd /net || { echo "Can't read /net.  Make sure you've logged in to the Samba network, and try again."; exit 1; } do_stuff more_stuff
Обратите внимание на пробел между { и echo, а также на точку с запятой перед закрывающей }. Некоторые добавляют в начало скрипта команду set -e, чтобы их скрипты прерывались после каждой команды, вернувшей ненулевое значение, но этот трюк нужно использовать с большой осторожностью, поскольку многие распространённые команды могут возвращать ненулевое значение в качестве простого предупреждения об ошибке (warning), и совершенно необязательно рассматривать такие ошибки как критические. Кстати, если вы много работаете с директориями в bash-скрипте, перечитайте man bash в местах, относящихся к командам pushd, popd и dirs. Возможно, весь ваш код, напичканный cd и pwd, просто не нужен :). Вернёмся к нашим баранам. Сравните этот фрагмент:
find ... -type d | while read subdir; do     cd "$subdir" && whatever && ... && cd - done
с этим:
find ... -type d | while read subdir; do     (cd "$subdir" && whatever && ...) done
Принудительный вызов подоболочки заставляет cd и последующие команды выполняться в subshell'е; в следующей итерации цикла мы вернёмся в начальное местонахождение вне зависимости от того, успешной ли была смена директории или же она завершилась с ошибкой. Нам не нужно возвращаться вручную. Кроме того, предпоследний пример содержит ещё одну ошибку: если одна из команд whatever провалится, мы можем не вернуться обратно в начальный каталог. Чтобы исправить это без использования субшелла, в конце каждой итерации придётся делать что-то вроде cd "$ORIGINAL_DIR", а это добавит ещё немного путаницы в ваши скрипты.

18. [ bar == "$foo" ]

Оператор == не является аргументом команды [. Используйте вместо него = или замените [ ключевым словом [[:
[ bar = "$foo" ] && echo yes [[ bar == $foo ]] && echo yes

19. for i in {1..10}; do ./something &; done

Нельзя помещать точку с запятой ";" сразу же после &. Просто удалите этот лишний символ:
 for i in {1..10}; do ./something & done
Символ & сам по себе является признаком конца команды, так же, как ";" и перевод строки. Нельзя ставить их один за другим.

20. cmd1 && cmd2 || cmd3

Многие предпочитают использовать && и || в качестве сокращения для if ... then ... else ... fi. В некоторых случаях это абсолютно безопасно:
[[ -s $errorlog ]] && echo "Uh oh, there were some errors." || echo "Successful."
Однако в общем случае эта конструкция не может служить полным эквивалентом if ... fi, потому что команда cmd2 перед && также может генерировать код возврата, и если этот код не 0, будет выполнена команда, следующая за ||. Простой пример, способный многих привести в состояние ступора:
i=0 true && ((i++)) || ((i--)) echo $i   # выведет 0
Что здесь произошло? По идее, переменная i должна принять значение 1, но в конце скрипта она содержит 0. То есть последовательно выполняются обе команды i++ и i--. Команда ((i++)) возвращает число, являющееся результатом выполнения выражения в скобках в стиле C. Значение этого выражения — 0 (начальное значение i), но в C выражение с целочисленным значением 0 рассматривается как false. Поэтому выражение ((i++)), где i равно 0, возвращает 1 (false) и выполняется команда ((i--)). Этого бы не случилось, если бы мы использовали оператор преинкремента, поскольку в данном случае код возврата ++i — true:
i=0 true && (( ++i )) || (( --i )) echo $i    # выводит 1
Но нам всего лишь повезло и наш код работает исключительно по «случайному» стечению обстоятельств. Поэтому нельзя полагаться на x && y || z, если есть малейший шанс, что y вернёт false (последний фрагмент кода будет выполнен с ошибкой, если i будет равно -1 вместо 0) Если вам нужна безопасность, или вы сомневаетесь в механизмах, которые заставляют ваш код работать, или вы ничего не поняли в предыдущих абзацах, лучше не ленитесь и пишите if ... fi в ваших скриптах:
i=0 if true; then     ((i++)) else     ((i--)) fi echo $i   # выведет 1. 
Bourne shell это тоже касается:
# Выполняются оба блока команд: $ true && { echo true; false; } || { echo false; true; } true false

21. Касательно UTF-8 и BOM (Byte-Order Mark, метка порядка байтов)

В общем: в Unix тексты в кодировке UTF-8 не используют метки порядка байтов. Кодировка текста определяется по локали, mime-типу файла, или по каким-то другим метаданным. Хотя наличие BOM не испортит UTF-8 документ в плане его читаемости человеком, могут возникнуть проблемы с автоматической интерпретацией таких файлов в качестве скриптов, исходных кодов, файлов конфигурации и т.д. Файлы, начинающиеся с BOM, должны рассматриваться как чужеродные, так же как и файлы с DOS'овскими переносами строк. В шелл-скриптах: «Там, где UTF-8 может прозрачно использоватся в 8-битных окружениях, BOM будет пересекаться с любым протоколом или форматом файлов, предполагающим наличие символов ASCII в начале потока, например, #! в начале шелл-скриптов Unix» http://unicode.org/faq/utf_bom.html#bom5


22. echo "Hello World!"


Проблема в том, что в интерактивной оболочке Bash эта команда вызовет ошибку:
bash: !": event not found

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

Очевидное решение здесь не работает:
$ echo "hi\!" hi\!


Можно заключить эту строку в одинарные кавычки:
echo 'Hello World!'

Но самое подходящее решение здесь — временно выключить параметр histexpand. Это можно сделать командой set +H или set +o histexpand:
set +H echo "Hello World!"

Почему же тогда всегда не пользоваться одиночными кавычками? Представьте, что вы хотите получить информацию об mp3-файлах:
mp3info -t "Don't Let It Show" ... mp3info -t "Ah! Leah!" ...

Одинарные кавычки здесь не подходят, поскольку названия песен содержат апострофы в названиях, а использование двойных кавычек приведёт к проблеме с подстановкой истории команд (а если бы в именах файлов ещё и двойные ковычки содержались, получилось бы вообще черте что). Поскольку лично я (Greg Wooledge, автор текста) никогда не использую подстановку истории команд, я просто поместил команду set +H в свой .bashrc. Но это вопрос привычки и каждый решает для себя сам.

23. for arg in $*


В Bash'е, так же, как и в других оболочках семейства Bourne shell, есть специальный синтаксис для работы с позиционными параметрами по очереди, но $* и $@ не совсем то, что вам нужно: после подстановки параметров они становятся списком слов, переданных в аргументах, а не списком параметров по отдельности.

Вот правильный синтаксис:
for arg in "$@"

Или просто:
for arg

for arg соответствует for arg in "$@". Заключенная в двойные кавычки переменная "$@" — это специальная уличная магия, благодаря которой каждый аргумент командной строки заключается в двойные кавычки, так что он выглядит как отдельное слово. Другими словами, "$@" преобразуется в список "$1" "$2" "$3" и т.д. Этот трюк подойдёт в большинстве случаев.

Рассмотрим пример:
#!/bin/bash # неправильно for x in $*; do echo "parameter: '$x'" done

Этот код напечатает:
$ ./myscript 'arg 1' arg2 arg3 parameter: 'arg' parameter: '1' parameter: 'arg2' parameter: 'arg3'

Вот как это должно выглядеть:
#!/bin/bash # правильно! for x in "$@"; do     echo "parameter: '$x'" done


$ ./myscript 'arg 1' arg2 arg3 parameter: 'arg 1' parameter: 'arg2' parameter: 'arg3'

24. function foo()


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

Некоторые версии bash позволяют одновременно использовать и function, и (), но ни в одной другой оболочке так делать нельзя. Некоторые интерпретаторы, правда, воспримут function foo, но для максимальной совместимости лучше использовать:
foo() {  ... }

25. echo "~"


Замена тильды (tilde expansion) происходит только когда символ ~ не окружён кавычками. В этом примере echo выведет ~ в stdout, вместо того, чтобы вывести пользовательский домашний каталог.

Экранирование переменных с путями, которые должны быть выражены относительно домашнего каталога, должно производиться с использованием $HOME вместо ~.
"~/dir with spaces"       #  "~/dir with spaces" ~"/dir with spaces"       # "~/dir with spaces" ~/"dir with spaces"       # "/home/my photos/dir with spaces" "$HOME/dir with spaces"   # "/home/my photos/dir with spaces"

26. local varname=$(command)


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

Поэтому эти команды лучше разделять:
local varname varname=$(command) rc=$?

http://habrahabr.ru 

суббота, 18 февраля 2012 г.

RHCE prepare...


IMPORTANT STEPS:
1. REMEMBER to ENABLE list of services!
can use system-config-services
2. /etc/inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward
3. find /var/log -cmin -1
4. ... BRAIN ...

********************************************
TIPS&TRICKS:

*/2 5-10 * * 1,5 free
Every 2 minutes from 5am to 10am Monday and Friday

Xorg -configure

Report: sar -A
Data path: /var/log/sa (sar -f saDD)
Schedule definition: /etc/cron.d/sysstat

directories for collaboration:
chmod g+s dir
create group shared_grp
chgrp shared_grp dir
Add users to shared_grp

rpm -ivh new_kernel.rpm

****************************************
CHAGE UTILITY :
Change aging: chage -E YYYY-MM-DD user
-m Specifies the minimum number of days between which the user must change passwords. If the value is 0, the password does not expire.
-M Specifies the maximum number of days for which the password is valid. When the number of days specified by this option plus the number of days specified with the -d option is less than the current day, the user must change passwords before using the account.
-d Specifies the number of days since January 1, 1970 the password was changed
-I Specifies the number of inactive days after the password expiration before locking the account. If the value is 0, the account is not locked after the password expires.
-E Specifies the date on which the account is locked, in the format YYYY-MM-DD. Instead of the date, the number of days since January 1, 1970 can also be used.
-W Specifies the number of days before the password expiration date to warn the user.
Examples:

List a users passowrd expiration info

[root@rhel ~]# chage --list username
Set an expiration based on a maximum number of days for which the password should be valid.

[root@rhel ~]# chage -M 120 username
To only allow a user to change their password every 10 days, and no more

[root@rhel ~]# chage -m 10 username
Apply immediate expiration

[root@rhel ~]# chage -d 0 username

*****************************************
HTTP/APACHE:

AuthType Defines the authentication type
AuthName Adds a comment for the user to see on login
AuthUserFile Specifies the file used to define username and password
AuthGroupFile Is similar to the user file but for groups
Require Specifies the users or groups that can log in

service httpd configtest

HTTP/HTTPS

Configure a virtual host
NameVirtualHost *:80
ServerName docs.example.com
DocumentRoot /path

Configure private directories
AuthType basic
AuthName “private rhel1?
AuthUserFile /www/.rhel1_priv_user
Require user name
Order deny,allow
Deny from all
Create user/password file:
htpasswd -c /www/.rhel1_priv_user user

Deploy a basic CGI application
Directory Options +ExecCGI
AddHandler cgi-script .pl .cgi
cgi-bin/hello.pl:
print “Content-type: text/html\n\n”;
print “hello!”;

Configure group-managed content
groupadd webdesigners
add users to webdesigners
mkdir /www/site1
chgrp apache.webdesigners /www/site1
chmod 775 /www/site1
chmod g+s /www/site1


context:
httpd_sys_content_t=content
httpd_sys_script_exec_t=scripts
httpd_log_t=logs

AConfigure host-based and user-based security for the service
Host
use iptables
/etc/httpd/conf/httpd.conf:
Allow from good_ip
Deny from all
Order deny,allow
User
/etc/httpd/conf/httpd.conf:
Use AuthType Basic

# semanage fcontext -a -t httpd_sys_content_t "/www/testsite(/.*)?"
Next we restore context recursively...

# restorecon -F -R -v /www/testsite
# setsebool -P httpd_enable_cgi on

****************************************
ISCSI :

# iptables -I INPUT -p tcp -m tcp --dport 3260 -j ACCEPT

server:
# service tgtd start
# chkconfig tgtd on
adding an XML entry to the /etc/tgt/targets.conf
backing-store /dev/virtstore/virtimage1 #LUN1
backing-store /var/lib/tgtd/virtualization/virtimage2.img #LUN2
write-cache off

# service iscsid start
# chkconfig iscsid on
/var/lib/iscsi/ifaces
discovery:
# iscsiadm -m discovery -t st -p IP
192.168.1.10:3260,1 iqn.2011-07.com.example.server1:trial
login:
# iscsiadm -m node -T iqn.2011-07.com.example.server1:trial -p 192.168.1.10 -l
/var/lib/iscsi...
umount:
# iscsiadm -m node -T iqn.2011-07.com.example.server1:trial -p 192.168.1.10 -u

For permanent add string to /etc/fstab

****************************************
KICKSTART:

Kickstart source Option format
DVD drive ks=cdrom:/directory/ks.cfg
Hard Drive ks=hd:/device/directory/ks.cfg
Hard Drive ks=hd:LABEL=FOOBAR:/path/to/ks.cfg
Other Device ks=file:/device/directory/ks.cfg
HTTP Server ks=http://server.mydomain.com/directory/ks.cfg
FTP Server ks=ftp://server.mydomain.com/directory/ks.cfg
NFS Server ks=nfs:server.mydomain.com:/directory/ks.cfg
linux ks=http://server.mydomain.com/kickstart.cgi kssendmac

#ksvalidator

****************************************
LDAP/KERBEROS:

yum install openldap openldap-clients nss_ldap

system-config-authentication : both LDAP or Kerberos
dc=example,dc=com
ldap://server1.example.com
download certificate:
ftp://server1/pub/EXAMPLE-CA-CERT

service sshd restart
ssh ldapuserX@stationX.example.com


TLS checking :
#openssl s_client -connect server1.example.com:PORT

/var/log/messages
/var/log/secure

ldapsearch -x Z

****************************************
LUKS CRYPTO F.S:

# cryptsetup luksFormat /dev/sdb1
# cryptsetup luksOpen /dev/sdb1 mynew_data
# mkfs.ext4 /dev/mapper/mynew_data
In the /etc/crypttab
mynew_data /dev/sdb1
In the /etc/fstab
UUID=f8b694a6-916d-4ffa-8e5c-a7ed8ab25b5d /mynew_data ext4
#mount -a

****************************************
MOUNT:

# mount -t cifs //server/share /mnt --verbose -o user=username
# mount -o rw -t nfs hostname:/mountpoint /mnt

in /etc/sysconfig/autofs --timeot
chkconfig autofs on; service autofs start

automount
/etc/auto.master
/misc /etc/auto.misc
/etc/auto.misc
cd -fstype=iso9960,ro,nosuid,nodev :/dev/cdrom
w/NIS * -fstype=nfs server1:/home/user/&
w/LDAP * -rw,soft,intr 192.168.0.1:/home/guests/&
myprojectv -rw,soft,intr 192.168.0.1:/home/guest :NFS

****************************************
NDS/NAMED:

/etc/named.conf
options
{
forwarders { 192.168.0.254; };
forward only;
}

chown root:named .zone
chmod 640 .zone
restorecon .zone

service named configtest
netstat -tulpn | grep named

chmod 640 `find ./ -type f -print`
chown named.named `find ./ -type f -print`


Configure a caching-only name server
named.conf:
allow-query { good_ips; };
recursion yes;

Configure a caching-only name server to forward DNS queries
named.conf:
allow-query { good_ips; };
forward only;
forwarders { forwarder_ip; };
recursion yes;

****************************************
Networking acces, basic services/utilites:

/etc/hosts.allow
in.telnetd@192.168.0.254:192.168.0.
sshd:ALL EXCEPT .cracker.org EXCEPT trusted.cracker.org
[bin,bin,bin...]:.example.com 127. [::1] !!!NOCIDR [fe80::]/64
sshd:[fe80::]/64
trailing dot - network
leading dot - domain

used /etc/services
includedir /etc/xinetd -overwritten by individual conf
/etc/xinet.d/.
#default off
{ disable = yes }
#need on ?:
{ disable = no
server = /path/to/bin}

/var/log/secure -xinetd
/var/log/messages -iptables

xterm -e "cd /var/log; tail -f messages secure" &
iptables -I INPUT 1 -j LOG

netstat -tulpn | grep service
ip addr show

/sbin/sysctl -w net.ipv4.ip_forward=1
sysctl -p
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -j LOG
iptables -t NAT -A POSTROUTING -o eth0 -j MASQUERADE

iptables -t nat -A PREROUTING -p tcp --dport 5001 -j DNAT --to-destination 10.10.10.10:25
iptables -t nat -A POSTROUTING -p tcp --dport 25 -j MASQUERADE

iptables -t nat -I PREROUTING -p tcp –dport 8800 -j DNAT –-to-destination 192.168.101.3:80
iptables -I INPUT -p icmp --icmp-type echo-request -j DROP :IPv4only
iptables -I INPUT -p icmp --icmp-type destination-unreachable -j DROP

iptables -nvL --line-numbers
./route-eth0
10.10.10.0/24 via 192.168.0.1 dev eth0

Server /etc/rsyslog.conf
$ModLoad imudp.so
$UDPServerRun 514

CLient /etc/rsyslog.conf
*.* @IP

DHCP:
DHCPDARGS="eth0"
dhcpd.conf.sample
service dhcpd configtest

NTP:
1.modify /etc/ntp/conf
2.start ntp
3.enable ntp at startup
4.cofig firewall udp 123
5.verify
open udp port 123 on server
Synchronize time using other NTP peers
Test:
ntpdate -q 123.123.56.123
Configure ntp.conf:
server 123.123.56.123 [iburst]

ping6 -c1 1:2:3 -I eth0
ssh 1:2:3%eth0
hot -t AAAA host.name.com
sysctl -a | grep ipv4

****************************************
NFS:

NFS v4. No tcpwrappers.

service nfs restart
-A -INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 2049 -j ACCEPT

# yum install nfs-utils nfs4-acl-tools portmap
in /etc/exports
/directory3 192.168.1.0/255.255.255.0!(options) *.redhat.com(no_root_squash)

# chkconfig nfs on; service nfs on
# chkconfig netfs on; service netfs on

# exportfs
# showmount -e
service nfs status

chcon -R -t public_content_t /nfs/share

Install service
“Provide network shares to specific clients”
Configure the service to start when the system is booted
Configure SELinux support
Configure static lockd, statd, mountd, rquotad ports in /etc/sysconfig/nfs
Update /etc/sysconfig/iptables:
open those ports

RQUOTAD=875
LOCKDTCP=32803
LOCKDUDP=32769
MOUNTD=892
STATD=662
rpcbindTCP=111
rpcbindUDP=111

****************************************
NSS/PAM:

Ключевое слово
Описание
Required («Обязательно») Если модуль срабатывает успешно, то PAM продолжает вычислять остающиеся записи для группы управления, и результаты будут определены результатами остающихся модулей. Если нет, то PAM продолжит вычисление, но возвратит сбой вызывавшему приложению.
Requisite («Необходимо») Если модуль срабатывает успешно, PAM продолжает вычислять записи группы управления. Если нет, то PAM произведет возврат вызывавшему приложению без дальнейшей обработки.
Sufficient («Достаточно») Если модуль сработает успешно, то PAM возвратит успешный результат вызывавшему приложению. Если нет, то PAM продолжит вычисление, но результаты будут определены последующими модулями.
Optional («Необязательно») PAM игнорирует результаты модуля, если это не единственный модуль, указанный для группы управления.
Include («Включить») PAM включает в себя содержимое файла настройки PAM, на который дается ссылка, а также содержащиеся в нем процессы и записи.

Откройте файл the /etc/pam.d/system-auth, затем прокрутите экран вниз и вставьте строку "session optional map_mkhomedir.so skel=/etc/skel umask=0644" перед последней строкой в разделе сеанса (см. рис. 16).
Эта строка настраивает PAM на создание домашнего каталога для пользователя, если такового еще не существует. Она будет использовать /etc/skel в качестве «скелета» шаблона и назначит маску прав 0644 (чтение и запись для владельца, чтение для основной группы и чтение для всех остальных) новой папке.

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

****************************************
SAMBA/SMB:
User access:
Configure users permissions in smb.conf and DAC!!!
Host access:
Use iptables

Global conf is overwriten by local.
Users must have local accounts.
useradd -a student
By default users can access to home dirs:
smbclient //IP/student

root mount:
mount -t cifs /host/dir -o user=student

/etc/fstab
credentials=/etc/red.txt

chcon -R -t samba_share_t /smb/share
setsebool -P samba_export_all_rw on

grep -E 'netbios|microsoft-ds' /etc/services
iptables -I INPUT -p tcp --dport 137:139 -j ACCEPT
iptables -I INPUT -p tcp --dropt 445 -j ACCEPT

mkdir /legal
chgrp legal /legal
chmod 3770 /legal
[legal]
path=/legal
valid users = @legal,user :can access
write list=@legal :can write
create mask=3770
directory mask =3775
Provide network shares suitable for group collaboration
add group workers (groupadd name; net rpc group add name)
add users to group (useradd name; net rpc user add username)
In smb.conf create a section like:
[shared]
path = /shared
force group = +workers :ctr as primary group workers
valid users = @workers viewer
write list = @workers

writeable = yes :can write any if=DAC > writelist
guest ok = yes :can access w/o pass

****************************************
SELinux:

# getenforce
# setenforce 0|1
# vim /etc/selinux/config
SELINUX=disabled

#/usr/sbin/getsebool -a
/usr/sbin/setsebool -P httpd_use_nfs on
/usr/sbin/setsebool -P httpd_use_nfs off
/usr/sbin/semanage boolean -l | grep nfs

grep vsftpd /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypool

chcon --reference shablon target
semanage fcontext -a -t public_content_t "/var/ftp(/.*)?"

example:
# setsebool -P httpd_enable_cgi on
Notice the -P we add in there, that is to make the change persistant across a reboot

#ps -Z
#ls -lZ

****************************************
SMTP
(MTA) to accept inbound email from other systems:

Configure /etc/postfix/main.cf:
myhostname Defines the full hostname of the Postfix server
mydomain Defines the domain name
myorigin Defines the name that outgoing mail originates from
inet_interfaces Identifies the interface on which to receive mail
mydestination Defines the domains for which Postfix accepts mail
mynetworks Lists trusted networks
virtual_alias_maps Defines virtual aliases for incoming mail

Configure an MTA to forward (relay) email through a smart host
Configure /etc/postfix/main.cf:
relayhost = host

Install the packages needed to provide the service
yum install postfix

Configure SELinux to support the service
getsebool -a | grep postfix

Configure the service to start when the system is booted
chkconfig postfix on

Host:
Use iptables
Update /etc/sysconfig/iptables:open tcp ports 25

Configure host-based and user-based security for the service
User:
/etc/postfix/main.cf:
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

service saslauthd start
service saslauthd start
chkconfig saslauthd on

Dovecot:
login trusted networks = id.net
mail_location = mbox:~/.mail:INBOX=/var/spool/mail/%u
then second times to log as user for DOVECOT crt files

****************************************
SSH:

ssh bringing X (required to run programs like system-config-users remotely)

# ssh -X user@host

Display debugging messages as it connects. Useful if you have having some issues connecting to a certain machine.

# ssh -v user@host

ssh to a custom port:

# ssh -p port_number user@host
1. Local port forwarding

ssh -L 1111:localhost:2222 username@remotehost
все пакеты приходящие на порт 1111 локалной машины (localhost) отправляются на порт 2222 удаленной машины (remotehost).

2.Remote port forwarding

ssh -R 2222:localhost:1111 username@remotehost
все пакеты приходящие на порт 2222 удаленной машины перенаправляются на вшау локальную машину, на порт 1111

Для того чтобы перенаправлялись и внешние пакеты, пришедшие на локальный порт 1111, нужно добавить опцию -g

****************************************
KVM/Virtualizations :

#virt-manager

To start a vm type:
# virsh start machninename01

To shutdown:
# virsh shutdown machninename01

To destroy:
# virsh destroy machninename01

To gain access to a virtual console:
# virsh console machninename01

To congifure the machine to launch at boot:
# virsh autostart machninename01

****************************************
VNC:

#vncpasswd
#vncserver
~/.vnc/xstartup
#!/bin/sh

# Uncomment the following two lines for normal desktop:
unset SESSION_MANAGER
exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
twm &


in /etc/sysconfig/vncservers
VNCSERVERS="2:myusername"
VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -nohttpd"

****************************************
VSFTPD/FTP:

# iptables -I INPUT 5 -p tcp -m tcp --dport 20 -j ACCEPT
# iptables -I INPUT 5 -p tcp -m tcp --dport 21 -j ACCEPT

semanage fcontext -a -t public_content_t "/var/ftp(/.*)?"
restorecon -F -R -v /var/ftp
chcon -R -t public_content_t /nfs/share

setsebool -P allow_ftpd_full_access on

/etc/sysconfig/iptables
IPTABLES_MODULES="ip_conntrack_ftp"

users access:
user_list -add users
userlist_deny = NO
userlist_enable=YES
local_enable=YES

anonymous-only download:
anonymous_enable=YES
anon_upload_enable=NO
local_enable=NO

****************************************
YUM/REPO:

# yum groupinstall "Virtualization"
# yum update kernel


*/repomd.xml -time stamp, chksum
*/primary.xml.gz -list of RPM
*/filelists.xml.gz -file list
*/other.xml.gz -other inf
*/comps.xml -group RPM install

rpm -ql aide -list of files
rpm -qi aide -package information
rpm -V aide -verify integrity
rpm -qf /var/lib/aide -which package provide

Local repos:
[mylocal]
name=mylocal
baseurl=file:///directory/path/to/repo/
enabled=1
gpgcheck=0

# createrepo -v .


Network repos:
cp -a /mnt/cdrom/. /var/ftp/pub/repo :FTP
ln -s ../../pub/repo /var/www/html/repo :HTTP
chcon -h -R -t httpd_sys_content_t /var/ftp/pub/repo
/etc/exports
/var/ftp/pub *(ro) :NFS


# createrepo -v .

Build a simple RPM that packages a single file
rpmdev-setuptree
cd ~/rpmbuild
rpmdev-newspec SPEC/hello.spec
edit SPEC/hello.spec
rpmbuild -ba SPEC/hello.spec


****************************************




понедельник, 28 декабря 2009 г.

HOW-TO`s

Русский шрифт в /etc/rc.d/rc.font

#!/bin/sh
#
# This selects your default screen font from among the ones in
# /usr/share/kbd/consolefonts.
#
unicode_start LatArCyrHeb-16
for i in 1 2 3 4 5 6;do
echo -ne "\033%G" >/dev/tty$i
done

Примечание: если вам понравился шрифт, который стоял по-умолчанию, вместо LatArCyrHeb-16 пропишите cyr-sun16

Раскладка клавиатуры в /etc/rc.d/rc.keymap

#!/bin/sh
# Load the keyboard map. More maps are in /usr/share/kbd/keymaps.
if[ -x /usr/bin/loadkeys ]; then
/usr/bin/loadkeys /usr/share/kbd/keymaps/i386/qwerty/ru-utf.map.gz
fi

Локаль в /etc/profile.d/lang.sh

#!/bin/sh
# Set the system locale. (no, we don't have a menu for this ;-)
# For a list of locales which are supported by this machine, type:
# locale -a

# en_US is the Slackware default locale:
#export LANG=en_US
export LANG=ru_RU.UTF-8

# 'C' is the old Slackware (and UNIX) default, which is 127-bit
# ASCII with a charmap setting of ANSI_X3.4-1968. These days,
# it's better to use en_US or another modern $LANG setting to
# support extended character sets.
#export LANG=C

# There is also support for UTF-8 locales, but be aware that
# some programs are not yet able to handle UTF-8 and will fail to
# run properly. In those cases, you can set LANG=C before
# starting them. Still, I'd avoid UTF unless you actually need it.
#export LANG=en_US.UTF-8

# Another option for en_US:
#export LANG=en_US.ISO8859-1

# One side effect of the newer locales is that the sort order
# is no longer according to ASCII values, so the sort order will
# change in many places. Since this isn't usually expected and
# can break scripts, we'll stick with traditional ASCII sorting.
# If you'd prefer the sort algorithm that goes with your $LANG
# setting, comment this out.
export LC_COLLATE=C

# End of /etc/profile.d/lang.sh

и /etc/profile.d/lang.csh

#!/bin/csh
# Set the system locale. (no, we don't have a menu for this ;-)
# For a list of locales which are supported by this machine, type:
# locale -a

# en_US is the Slackware default locale:
##setenv LANG en_US
setenv LANG ru_RU.UTF-8

# 'C' is the old Slackware (and UNIX) default, which is 127-bit
# ASCII with a charmap setting of ANSI_X3.4-1968. These days,
# it's better to use en_US or another modern $LANG setting to
# support extended character sets.
#setenv LANG C

# There is also support for UTF-8 locales, but be aware that
# some programs are not yet able to handle UTF-8 and will fail to
# run properly. In those cases, you can set LANG=C before
# starting them. Still, I'd avoid UTF unless you actually need it.
#setenv LANG en_US.UTF-8

# Another option for en_US:
#setenv LANG en_US.ISO8859-1

# One side effect of the newer locales is that the sort order
# is no longer according to ASCII values, so the sort order will
# change in many places. Since this isn't usually expected and
# can break scripts, we'll stick with traditional ASCII sorting.
# If you'd prefer the sort algorithm that goes with your $LANG
# setting, comment this out.
setenv LC_COLLATE C

# End of /etc/profile.d/lang.csh


*****************************************
AIDE
1. Установка пакета aide-0.11-1.2.el4.rf.i386.rpm
2. Правка конфигурационного файла /etc/aide.conf по типу:
/etc p+i+u+g
!/etc/mtab
3. Создание снимка указанной ф.с:
# aide --init
4. Копируем базу из /var/lib/aide/aide.db.new.gz в /var/lib/aide/aide.db.gz
5. Создаём скрипт проверки:
#!/bin/bash
ReportDir=/usr/local/stat/report
LogFile=/var/log/aide.log
Hostname="www"
Mail='unix@domain.kz'
Date=`date '+%Y-%m-%d'`
cd $ReportDir
/usr/sbin/aide --check
SZ=`ls -l /var/log/aide.log | awk {'print $5'}`;
if [ $SZ -eq 0 ]; then
/bin/logger -p local0.info "Integrity Check was succesfull complete. Nothing changes."
else
# service sendmail start; sleep 15;
mail -s "Integrity Checking Warning from ${HOSTNAME}" $Mail < $LogFile # sleep 15; service sendmail stop; fi exit 0 6. Далее можно сделать снапшот системы и забакапить его на CD к примеру, для дальнейшей сверки в случае непрошенного вторжения:
# mkisofs -V Aide_DB`date +%F` -J -R -o aide.iso /Aide/directory

# cdrecord -v -eject aide.iso


Всё! Всем удачи и целостности в НГ !!!

понедельник, 28 сентября 2009 г.

Измышлизмы

Пишу для всех... Пишу обо всём... Пишу то что слышал или читал, и то что по жизни считаю схожим моему мнению. Возможно тут будет много чужих слов, перефразированных или написанных по памяти с ошибками, но надеюсь что от этого ценность их не уменьшиться, а может даже и наоборот... Вобщем решил весь этот коломбур обозначить словом - измышлизмы !... Добро пожаловать! :)
ЗЫ
Конечно же посвящается моей дочери, и очень надеюсь на то что она когда либо прочтёт это, и сделает для себя правильные выводы которые помогут ей в жизни.

Думаю первое с чего можно начать это филосовская фраза Джимми Хендрикса :

"Когда власть любви превзойдёт любовь к власти, настанет Мир на Земле"

Дети ничем не обязаны родителям, а родители обязаны детям всем.

Не суди и судим не будешь.

Умение говорить ценится высоко... а умение слушать ещё больше.

Жизнь - это когда с нами происходит не то, что мы запланировали.

Афоризмы Альберта Энштейна:

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

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

Воображение важнее, чем знание.

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

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

Единственный разумный способ обучать людей - это подавать им пример.

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

Истина - это то, что выдерживает испытание опытом.

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

Настоящий прогресс человечества зависит не столько от изобретательного ума, сколько от сознательности.

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

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

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

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

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

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

Воображение это всё . Это предварительный показ предстоящих событий в жизни.
---

четверг, 11 июня 2009 г.

DB bases.

1.MySql
#mysql -u user -ppass base_name <> base_dump.sql #export
#mysqlshow -u user -ppass #show bases
Flash password RH:
#mysqld_safe --skip-grant-tables --user=root &
#mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('newpwd‘) WHERE User=’root’;
mysql> FLUSH PRIVILEGES;
Show DB:
#mysql> show databases;
Clead DB:
#mysql> drop database basename;


среда, 10 июня 2009 г.

Bash bases.

6.3.1 Общее

![numb] — запуск строки из истории (history);
!str — запуск ближайшей строки соответствующей маске str из истории (history);
\ — продолжение текущей строки на другой строке или экранирование специального символа после данного символа (\$);
; — разделитель команд;
() — выполнения сценария в скобках в другой подоболочке;
(()) — включение выражений с «С» синтаксисом;
[] — включение условных операций с синтаксисом команды test;
“pwd” — определение строки с разрешением подстановки значений переменных;
'pwd' — определение строки с запрещением подстановки значений переменных;
`pwd` — результат выполнения команды pwd;
$(x) — выполнение команды x и возврат результата (подобно `x`);
x=pwd — определение переменной окружения x и присвоение ей строки pwd;
x='34' — определение переменной окружения x и присвоение ей строки '34';
x[2]=pwd — определение массива x и присвоение его элементу 2 строки pwd;
x=(zero one two three) — определение массива x и заполнение четырех его элементов;
x=([0]=zero [3]=three [2]=two [1]=one) — определение массива x и заполнение четырех его элементов по выбору;
$(( 100/3 )), $[100/3] — выполнение простых целочисленных операций.

Примеры:
a=4; echo $[a=$a+4] $[a+=4] $[a=a+4]
a=4; echo $[a=$a+4, a+=4, a=a+4]
$[2!=2] $[2!=3]
$[a=2<3] $a
Операции:
id++, id-- — постфиксное увеличение/уменьшение значения переменной на 1
++id, --id — префиксное увеличение/уменьшение значения переменной на 1
-, + — унарные минус и плюс
!, ~ — логическое и побитовое отрицание
** — возведение в степень
*, /, % — умножение, деление, получение остатка от деления
+, - — сложение, вычитание
< <, > > — побитовый сдвиг влево и вправо
<=, >=, <, > — сравнение
==, != — равенство и неравенство
& — побитовое И
^ — побитовое исключающее ИЛИ НЕ a^b – это а или с… но не в
| — побитовое ИЛИ
&& — логическое И
|| — логическое ИЛИ
выр1?выр2:выр3 — условное вычисление
=, *=, /=, %=, +=, ?=+ — присваивание
выр1,выр2 — запятая
() — выделение более приоритетного участка выражения

$x, ${x} — подстановка значения переменной/параметра x
${!x} — косвенная подстановка значения переменной/параметра указанного в x;
${#x} — косвенная подстановка значения переменной/параметра указанного в x,

если параметр – * или @, подставляется количество позиционных параметров,
если параметр – массив с индексом * или @, подставляется количество элементов массива;

${x:?»Error, no bar»} — генерировать ошибку если x не определена или равна нулю;
${x?»Error, no bar»} — -//-;
${x:="foose"} — присвоить значение по умолчанию если x не определена или равна нулю;
${x="foose"} — -//-;
${x:offset:lenght}, ${x:offset} — возвращает часть от x начиная с offset длиной lenght;

В качестве длины и смещения могут выступать:

  • арифметические выражения;
  • смещение отрицательное число – отсчитывается с конца значения параметра;
  • параметр – @, результат – позиционных параметров, начиная с параметра ;
  • параметр – массив с индексом @ или *, результат – элементов массива, начиная с ${параметр[m]};

${x:+"foose"} — если переменная определена то вместо неё используется “foose”;
${x+"foose"} — -//-;
${x:-"foose"} — если переменная определена то она используется иначе используется “foose”;
${x-"foose"} — -//-;
${пар#шабл} — ??
${пар##шабл} — ??
${пар%шабл} — ??
${пар% %шабл} — ??
${пар/шабл/стр} — заменяется первая, самая длинная подстрока значения параметра, на указанную строку;
${пар/ /шабл/стр} — заменяются все самые длинные подстроки значения параметра, на указанную строку;
${array[@]} — обращение сразу ко всему массиву;
$'\n' — вставка управляющего символа в строку;
Comm && — выполняет действие после выражения если команда неудачна;
Comm || — выполняет действие после выражения если команда удачна;
MYVAR#*fo — отсекает от начала переменной MYVAR самую короткую часть удовлетворяющую маске *fo;
MYVAR##*fo — отсекает от начала переменной MYVAR самую длинную часть удовлетворяющую маске *fo;
MYVAR%fo* — отсекает от конца переменной MYVAR самую короткую часть удовлетворяющую маске fo*;
MYVAR% %fo* — отсекает от конца переменной MYVAR самую длинную часть удовлетворяющую маске fo*;
MYVAR:2:5 — возвращает часть строки MYVAR которая начинается с 2 символа и заканчивается 5;

6.3.2 Служебные переменные языка

$# — количество фактических аргументов;
$- — флаги (однобуквенные), указанные при запуске shell или установленные посредством set.
$? — код возврата последней команды;
$$, $PPID — PID текущего процесса (скрипта);
$! — PID последнего запущенного фонового процесса;
$* — раскрывает единственное слово, содержащее список всех позиционных парам;
$@ — ссылка на все аргументы команды отделенные пробелами;
$0 — имя команды в командной строке;
$n, ${n} — аргумент n командной строки (n = 1...);

6.3.3 Основные переменные окружения оболочки

PWD — текущий рабочий каталог;
UID — цифровой идентификатор текущего пользователя;
umask — содержит маску прав доступа по которой создаются новые файлы;
BASH — полный путь вызова BASH;
BASH_VERSION — версия данного экземпляра BASH;
EDITOR — содержит имя редактора используемого для редактирования некоторых конфигурационных файлов;
PAGER — содержит имя программы для отображения информационных страниц (типа more);
SHLVL — количество запущенных BASH;
REPLY — содержит последнюю строку ввода;
RANDOM — содержит случайное число в диапазоне 0..32767;
SECONDS — время в секундах от запуска BASH;
HISTCMD — номер текущей команды в истории;
IFS — цепочка символов разделителей полей;
PATH — пути поиска команд;
HOME — домашний каталог текущего пользователя;
MAIL — имя файла в который поступает электронная почта;
LOGNAME — имя пользователя использованное для входа в систему;
SHELL — имя интерпретатора команд;
LD_LIBRARY_PATH — описания пользовательских путей к динамическим библиотекам;
DISPLAY — описывает адрес дисплея для X-приложений;
LANG — переменная локали;
TERM — тип пользовательского терминала;
INPUTRC — содержит имя файла параметров для библиотеки readline, определяющей параметры ввода с клавиатуры;
PS1,PS2 — описывает вид приглашения в командной строке;
TZ — информация о часовом поясе;
MALLOC_CHECK_ — указывает что делать с ошибками в функциях malloc, free:

= 0 — молча игнорировать все ошибки;
= 1 — сообщить об ошибке и продолжить работу;
= 2 — прервать (без сообщения);
= 3 — прервать и сообщить об ошибке.

MALLOC_TRACE — определяет путь для команды mtrace и функции в программе mtrace;

6.3.4 Основные операторы

& — выполнить команду до него в фоновом режиме;
if [ Condition ] — условный оператор ( if ( Condition ) – tch);
then — тело выполнения условия;
else — тело невыполнение условия;
elif [ Condition ] — совмещенная команда else if;
fi — окончание условного оператора;
for x in 1 2 3 4 — оператор цикла, в x перебираются значения за in ( foreach x (1 2 3 4) – tch ). Общая структура циклов:

for x in 1 2 3 4

do #тело цикла

done

while [ Condition ] — выполняет цикл пока верно условие Condition ( while ( Condition ) -tch );
until [ Condition ] — выполняет цикл до равенства условия Condition;
(repeat x expression – tch ) — выполняет повторение выражения x раз;
select x in list; — запрашивает выбор из списка и присваивает выбранное значение переменной ;
do — начало тела цикла определенного for, while, until;
done — конец тела цикла определенного for, while, until;
break — завершение цикла;
continue — продолжение цикла сначала;
case x in — команда выбора. Имеет структуру:

case "${x##*.}" in
gz) gzunpack ${SROOT}/${x} ;;
bz2) bz2unpack ${SROOT}/${x} ;;
*) echo «Неизвестный формат архива» exit ;;
esac

function func() { } — определяет функцию с именем func;
func a1 a2 a3 — вызов функции;

6.3.5 Встроенные команды

. file — выполнить все команды в файле после точки;
eval [attr] — выполнить команду заданную аргументами;
exec [prog] — сменить программу текущего процесса указанной, т.е. выполнить в данном процессе новую программу;
exit n — выход из сценария с кодом ;
shift [n] — сдвиг параметров командной строки на единицу (для доступа к параметрам с номером > 9 );
cd [dir] — сменить директорию;
pwd — получение имени текущей директории;
read x y — ввод строки из двух слов;
set x = str — инициализация переменной и установка различный настроек интерпретатора;
-A Name_A 1 2 3 4 5 — инициализация массива;
-V,-X — включение отладочного режима;
+V,+X — выключение отладочного режима;
unset x — отмена инициализации переменной;
export x — создает переменную окружения x и экспортирование её в систему;
-p — вывод всех экспортированных переменных.
local x — создает локальную переменную окружения которая не перекрывает глобальной (часто используется для функций);
declare — декларирование переменных и изменение их атрибутов;
trap — установка обработчиков сигналов в скрипте;
alias [имя=синоним] — создание псевдонимов или альтернативных имен команд;
unalias — удаление псевдонима;
test — проверка условий, используется в циклах;
getopts — разбор опций.

6.3.6 Операторы сравнения файлов

-e — существует;
-d — каталог;
-f — обычный файл;
-c — специальный файл;
-b — специальный блочный файл;
-p — специальный файл именованного канала;
-L — символическая ссылка;
-r — для чтения;
-w — для записи;
-x — исполняемый;
-z — файл пуст;
-s,(-z) — имя файла не нулевой длины;
(-o) — пользователь является владельцем файла;
fname1 -nt fname2 — fname1 новее fname2;
fname1 -ot fname2 — fname1 старше fname2;

6.3.7 Операторы сравнения цепочек символов, арифметических выражений и логические операторы

-z — строка пуста;
-n — строка не пуста;
=, (==) — строки равны;
!= — строки неравна;
-eq — равно;
-ne — неравно;
-lt,(< ) — меньше;
-le,(<=) — меньше или равно;
-gt,(>) — больше;
-ge,(>=) — больше или равно;
! — отрицание логического выражения;
-a,(&&) — логическое «И»;
-o,(||) — логическое «ИЛИ»

6.3.8 Перенаправления вывода

| — перенаправление вывода в канал;
< file — file записать в STDIN;
> file — STDOUT записать в file;
<> file — чтение и запись в файл;
>> file — STDOUT добавить в file;
<< str — определяет слово как признак окончания ввода;
2> file — STDERR записать в file (могут указываться дескрипторы других файлов);
1>&2 — STDOUT записать в STDERR;
2>&1 — STDERR записать в STDOUT;
&> file — STDOUT и STDERR записать в file;

6.3.9 Специальные символы (экранирование)

\n — новая строка
\b — возврат на один символ
\c — печать строки без символа новой строки
\f — переход к новой странице/экрану
\r — возврат каретки
\t — табуляция
\v — табуляция по вертикали
\\ — обратная косая черта
0nnn — восьмеричное число
xNN — шестнадцатеричное число

6.3.10 Маски (подстановка, может быть отключена опцией -f или set)

* — производная цепочка символов;
? — производный символ;
[...] — символ в скобках [A-Z]; "! и ^" – исключение символа.

6.3.11 Представление численных значений

045 — восьмеричное число (начинается с 0)
0x45, 0X32 — шестнадцатеричное число
[основание#]n — число с основанием (по умолчанию основание 10)

Примеры:
$[2#101] $[10#101] $[16#101]
$[16#FF] $[16#ff] $[0xFF]
$[64**2] $[64#@@]
$[64#z] $[64#Z]

понедельник, 4 мая 2009 г.

Commands_2

Список основных команд Linux. Все команды тестировались на Fedora и Ubuntu.
КомандаОписание
apropos whatisПоказать команды соответствующие строке. См. также threadsafe
man -t man | ps2pdf - > man.pdfСоздать pdf версию страницы мануала (man)

which commandПоказать полный путь к файлу команды

time commandВыполнить команду и отобразить время выполнения
time catЗапустить секундомер. Ctrl-d чтобы остановить его. См. также sw
nice infoЗапустить команду с низким приоритетом (”info” reader в данном случае)
renice 19 -p $$Установить shell (скрипту) низкий приоритет. Используется для неинтерактивных задач.
Навигация по директориям
cd -Перейти в предыдущую директорию
cdПерейти в $HOME директорию

(cd dir && command)Перейти в директорию, выполнить комманду (command) и вернуться в текущую директорию
pushd .Положить текущую директорию в стек, чтобы позже вернуться к ней с помощью popd
alias l='ls -l --color=auto'Быстрое отображение содержимого директории
ls -lrtСписок файлов по дате. См. также newest и find_mm_yyyy
ls /usr/bin | pr -T9 -W$COLUMNSНапечатать в 9 столбцов в ширину терминала

find -name '*.[ch]' | xargs grep -E 'expr'Искать ‘expr’ в текущей директории и в нижестоящих директориях. См. также findrepo

find -type f -print0 | xargs -r0 grep -F 'example'Поиск всех файлов по ‘example’ в текущей директории и ниже

find -maxdepth 1 -type f | xargs grep -F 'example'Поиск всех файлов по ‘example’ в текущей директории

find -maxdepth 1 -type d | while read dir; do echo $dir; echo cmd2; doneОбработать каждый элемент с несколькими командами (в цикле while)
find -type f ! -perm -444Найти файлы, которые не являются видимыми для всех (полезно для веб сайта)
find -type d ! -perm -111Найти директории не доступные для всех (полезно для web сайтов)
locate -r 'file[^/]*\.txt'Искать в кешированном индексе по именам.
look referenceБыстрый поиск (сортированный) словаря по префиксу
grep --color reference /usr/share/dict/wordsПодсвечивание мест где регулярное выражение появляется в словаре
Архивирование и сжатие

gpg -c fileЗашифровать файл

gpg file.gpgРасшифровать файл

tar -c dir/ | bzip2 > dir.tar.bz2Заархивировать директорию (папку) dir/

bzip2 -dc dir.tar.bz2 | tar -xРазархивировать архив (используйте gzip вместо bzip2 для файлов tar.gz)

tar -c dir/ | gzip | gpg -c | ssh user@remote 'dd of=dir.tar.gz.gpg'Создать зашифрованный архив директории (папки) dir/ на удаленном компьютере

find dir/ -name '*.txt' | tar -c --files-from=- | bzip2 > dir_txt.tar.bz2Создать архив для папки dir/ и всех вложенных папок

find dir/ -name '*.txt' | xargs cp -a --target-directory=dir_txt/ --parentsСоздать копию папки dir/ с вложенными папками

( tar -c /dir/to/copy ) | ( cd /where/to/ && tar -x -p )Скопировать (с правами доступа) папку copy/ в папку /where/to/

( cd /dir/to/copy && tar -c . ) | ( cd /where/to/ && tar -x -p )Скопировать (с правами доступа) содержимое папки copy/ в /where/to

( tar -c /dir/to/copy ) | ssh -C user@remote 'cd /where/to/ && tar -x -p' Скопировать (с правами доступа) папку copy/ на удаленный компьютер remote:/where/to

dd bs=1M if=/dev/sda | gzip | ssh user@remote 'dd of=sda.gz'Сделать резервную копию (сбекапить) жесткого диска и послать ее на удаленный компьютер
rsync (Эффективный сетевой копировщик файлов: Используйте опцию –dry-run для тестирования)

rsync -P rsync://rsync.server.com/path/to/file fileТолько отобразить различия. Делайте много раз чтобы проверить прошли ли нормально закачки

rsync --bwlimit=1000 fromfile tofileСкопировать локально с предельной скоростью. Это приятно для I/O

rsync -az -e ssh --delete ~/public_html/ remote.com:'~/public_html'Зеркальный веб сайт (используется шифрование и дешифрование)

rsync -auz -e ssh remote:/dir/ . && rsync -auz -e ssh . remote:/dir/Синхронизировать текушую папку с папкой на удаленном компьютере
ssh (Secure SHell)

ssh $USER@$HOST commandЗапустить команду command на удаленном хосте $HOST от имени пользователя $USER
(команда по умолчанию = shell)
ssh -f -Y $USER@$HOSTNAME xeyesЗапустить GUI команду на удаленном хосте $HOST от имени пользователя $USER

scp -p -r $USER@$HOST: file dir/Скопировать папку dir/ с правами доступа в домашнию папку пользователя $USER на хосте $HOST

ssh -g -L 8080:localhost:80 root@$HOSTПеренаправить соединения к $HOSTNAME:8080 наружу к $HOST:80

ssh -R 1434:imap:143 root@$HOSTПеренаправить соединения от $HOST:1434 к внутр. imap:143
wget (многоцелевой инструмент для скачивания)
(cd cli && wget -nd -pHEKk http://www.pixelbeat.org/cmdline.html)Сохранить веб страницу (как она открывается локально) в текущую директорию

wget -c http://www.example.com/large.fileПродолжить скачивание частично скаченного файла

wget -r -nd -np -l1 -A '*.jpg' http://www.example.com/Скачать множество файлов в текущую директорию

wget ftp://remote/file[1-9].iso/Ftp непосредственная поддержка globbing
wget -q -O- http://www.pixelbeat.org/timeline.html | grep 'a href' | headОтображать вывод напрямую (на экран)

echo 'wget url' | at 01:00Скачать url в 01:00 в текущую директорию

wget --limit-rate=20k urlСделать закачку с уменьшенной скоростью (ограничить скорость до 20 КB/s в этом примере)

wget -nv --spider --force-html -i bookmarks.htmlПроверить ссылки в файле

wget --mirror http://www.example.com/Оперативно обновлять локальную копию сайта (удобно использовать с cron)
Сетевые команды (Обратите внимание, что команды ifconfig, route, mii-tool, nslookup устарели)

ethtool eth0Отобразить статус сетевого устройства (интерфейса) eth0

ethtool --change eth0 autoneg off speed 100 duplex fullВручную установить скорость сетевого интерфейса (устройства)

iwconfig eth1Отобразить статус беспроводного интерфейса (устройства) eth1

iwconfig eth1 rate 1Mb/s fixedВручную установить скорость беспроводного интерфейса (устройства)
iwlist scanСписок беспроводных сетей в радиусе действия
ip link showСписок сетевых интерфейсов (устройств)

ip link set dev eth0 name wanПереименовать интерфейс (устройство) eth0 в wan

ip link set dev eth0 upВключить интерфейс eth0 (чтобы выключить - down)
ip addr showСписок ip адресов интерфейсов

ip addr add 1.2.3.4/24 brd + dev eth0Добавить (или удалить) ip адрес и маску (255.255.255.0)
ip route showВывести таблицу маршрутизации

ip route add default via 1.2.3.254Установить 1.2.3.254 в качестве шлюза по умолчанию
tc qdisc add dev lo root handle 1:0 netem delay 20msecДобавить 20мс латентность к устройству loopback (для тестирования)
tc qdisc del dev lo rootУбрать латентность добавленную выше
host pixelbeat.orgПоиск ДНС ip адреса по имени хоста или наоборот
hostname -iПоиск локального ip адреса (идентично host ‘hostname’)
whois pixelbeat.orgПоиск whois информации по имени хоста или ip адресу
netstat -tuplСписок интернет сервисов в системе
netstat -tupСписок активных соединений к системе (от системы)
Сетевые команды связанные с windows (Обратите внимание, что samba - это пакет который предоставляет всю windows специфичную поддержку сети)
smbtreeНайти windows компьютеры в сети. См. также findsmb

nmblookup -A 1.2.3.4Найти windows (netbios) имя, ассоциируемое с ip адресом

smbclient -L windows_boxСписок shares на windows компьютере или samba сервере

mount -t smbfs -o fmask=666,guest //windows_box/share /mnt/shareСмонтировать windows share (папку с открытым доступом)

echo 'message' | smbclient -M windows_boxПослать popup сообщение на windows комьютер (отключено по умолчанию в XP sp2)
Манипуляции с текстом (Обратите внимание, sed использует stdin и stdout, так что если Вы хотите редактировать файлы, добавляйте newfile)

sed 's/string1/string2/g'Заменить строку string1 строкой string2

sed 's/\(.*\)1/\12/g'Изменить строку anystring1 на anystring2

sed '/ *#/d; /^ *$/d'Убрать комментарии и пустые строки

sed ':a; /\\$/N; s/\\\n//; ta'Соединить строки (линии) с предшествующим \

sed 's/[ \t]*$//'Удалить предшествующие пробелы с строк

sed 's/\([\\`\\"$\\\\]\)/\\\1/g'Заескейпить активные метасимволы оболочки двумя ковычками
seq 10 | sed "s/^/ /; s/ *\(.\{7,\}\)/\1/"Выровнять числа по правой границе

sed -n '1000p;1000q'Напечатать 1000-ную строку

sed -n '10,20p;20q'Напечатать строки с 10 по 20-ую

sed -n 's/.*\(.*\).*/\1/ip;T;q'Получить title из HTML страницы

sort -t. -k1,1n -k2,2n -k3,3n -k4,4nОтсортировать IPV4 ip адреса
echo 'Test' | tr '[:lower:]' '[:upper:]'Перевести из одного регистра в другой
tr -dc '[:print:]' < /dev/urandomОтфильтровать не печатаемые символы
history | wc -lПосчитать число строк
Операции с множествами (Обратите внимание, что Вы можете export LANG=C для скорости. Это также полагает отсутствие линий дупликатов в файле)

sort file1 file2 | uniqОбъединение неотсортированных файлов

sort file1 file2 | uniq -dПересечение неотсортированных файлов

sort file1 file1 file2 | uniq -uРазность неотсортированных файлов

sort file1 file2 | uniq -uСимметрическая разность неотсортированных файлов

join -a1 -a2 file1 file2Объединение отсортированных файлов

join file1 file2Пересечение отсортированных файлов

join -v2 file1 file2Разность отсортированных файлов

join -v1 -v2 file1 file2Симметрическая разность отсортированных файлов
Математические операции
echo '(1 + sqrt(5))/2' | bc -lПростая математика (Вычисление числа φ). См. также bc
echo 'pad=20; min=64; (100*10^6)/((pad+min)*8)' | bcБолее сложная (целая). Этот пример показывает максимум FastE packet rate
echo 'pad=20; min=64; print (100E6)/((pad+min)*8)' | pythonПитон занимается математическими вычислениями
echo 'pad=20; plot [64:1518] (100*10**6)/((pad+x)*8)' | gnuplot -persistНапечатать FastE packet rate против packet size
echo 'obase=16; ibase=10; 64206' | bcКонвертация систем счисления (десятичную в шестнадцатиричную)
echo $((0x2dec))Конвертация систем счисления (шестнадцатиричную в десятичную)
((арифметическое расширение shell-а))
units -t '100m/9.69s' 'miles/hour'Unit конвертация (метрической системы в имперскую)
units -t '500GB' 'GiB'Unit конвертация (SI в IEC префиксы)
units -t '1 googol'Поиск определения
seq 100 | (tr '\n' +; echo 0) | bcДобавить столбец чисел. См. также add и funcpy
Календарь
cal -3Отобразить календарь
cal 9 1752Отобразить календарь для конкретного месяца года
date -d friКакая дата у текущей пятницы. См. также day
[ $(date -d "tomorrow" +%d) = "01" ] || exitЗавершить выполнение скрипта, если только сейчас не последний день месяца
date --date='25 Dec' +%AКакого числа будет рождество в текущем году
date --date='@2147483647'Перевести секунды прошедшие с epoch (1970-01-01 UTC) в дату
TZ=':America/Los_Angeles' dateСколько времени сейчас на Западном побережье США (используйте tzselect чтобы найти TZ)

echo "mail -s 'get the train' P@draigBrady.com < /dev/null" | at 17:45Напоминать по Email
echo "DISPLAY=$DISPLAY xmessage cooker" | at "NOW + 30 minutes"Напоминать в Popup окне
Locales (локализация)
printf "%'d\n" 1234Напечатать четырехзначное число сгруппированное соответственно локали
BLOCK_SIZE=\'1 ls -lСделать чтобы ls группировала тысячи соответственно локали
echo "I live in `locale territory`"Получить информацию из базы данных локали
LANG=en_IE.utf8 locale int_prefixИскать информацию о локали для конкретной страны См. также ccodes
locale | cut -d= -f1 | xargs locale -kc | lessСписок полей, доступных в базе данных локали
Перекодирование (команды iconv, dos2unix, unix2dos устарели)
recode -l | lessОтобразить доступные переходы (по 1 алиасу на каждой строке)

recode windows-1252.. file_to_change.txtПеревести Windows “ansi” в локальную (текущую) кодировку (auto делает CRFL перевод)

recode utf-8/CRLF.. file_to_change.txtПеревести windows utf8 в локальную (текущую) кодирувку

recode iso-8859-15..utf8 file_to_change.txtПеревести из кодировки latin9 (западная европейская) в utf8

recode ../b64 <> file.b64Кодирование base64

recode /qp.. <> file.qpРаскодирование с кавычками

recode ..HTML <> file.htmlПеревести text в HTML
recode -lf windows-1252 | grep euroПоиск в таблице символов
echo -n 0x80 | recode latin-9/x1..dumpПоказать символ в кодировке latin9 по коду
echo -n 0x20AC | recode ucs-2/x2..latin-9/xПоказать latin-9 encoding
echo -n 0x20AC | recode ucs-2/x2..utf-8/xПоказать utf-8 encoding
CDs (операции с CD дисками)

gzip < /dev/cdrom > cdrom.iso.gzСохранить копию CD с данными

mkisofs -V LABEL -r dir | gzip > cdrom.iso.gzСоздать образ CD диска из содержимого директории

mount -o loop cdrom.iso /mnt/dirСмонтировать CD образ на /mnt/dir (только для чтения)

cdrecord -v dev=/dev/cdrom blank=fastОчистить CDRW

gzip -dc cdrom.iso.gz | cdrecord -v dev=/dev/cdrom -Записать CD образ (используйте dev=ATAPI -scanbus для выбора устройства записи)

cdparanoia -BСохранить аудио треки с CD в wav файлы (сохранятся в текущую папку)

cdrecord -v dev=/dev/cdrom -audio *.wavСоздать аудио диск (audio CD) из всех wav файлов,
находящихся в текущей директории (см. также cdrdao)

oggenc --tracknum='track' track.cdda.wav -o 'track.ogg'Создать ogg файл из wav файла
Дисковое пространство (См. также FSlint)
ls -lSrСписок файлов, отсортированных по размеру (файл с наибольшим размером - последний)
du -s * | sort -k1,1rn | headПоказать пользователей в текущей папке с наибольшим объемом используемых данных.
См. также dutop
df -hПоказать свободное место на смонтированных файловых системах
df -iПоказать свободные индексные дескрипторы на смонтированных файловых системах
fdisk -lПоказать размеры разделов дисков и типы (запускается от root-а)
rpm -q -a --qf '%10{SIZE}\t%{NAME}\n' | sort -k1,1nСписок всех пакетов с размером дистрибутивов (размер - в Байтах)
dpkg-query -W -f='${Installed-Size;10}\t${Package}\n' | sort -k1,1nСписок всех пакетов с размерами установки (размер - в килобайтах) для debian дистрибутивов
dd bs=1 seek=2TB if=/dev/null of=ext3.testСоздать большой тестовый файл. См. также truncate
Мониторинг/отладка
tail -f /var/log/messagesМониторинг сообщений в log файле
strace -c ls >/dev/nullСумма/профиль системных вызовов, сделанных командой
strace -f -e open ls >/dev/nullСписок системных вызовов, сделанных командой
ltrace -f -e getenv ls >/dev/nullСписок библиотечных вызовов, сделанных командой
lsof -p $$Список путей, которые открывал процесс
lsof ~Список процессов, которые имеют открытые пути
tcpdump not port 22Отобразить сетевой (кроме ssh) траффик. См. также tcpdump_not_me
ps -e -o pid,args --forestИерархический список процессов
ps -e -o pcpu,cpu,nice,state,cputime,args --sort pcpu | sed '/^ 0.0 /d'Список процессов с % использования процессора
ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNSСписок процессов с используемой ими памятью (См. также ps_mem.py)
ps -C firefox-bin -L -o pid,tid,pcpu,stateСписок всех потоков для конкретного процесса
ps -p 1,2Список информации о процессах с конкретными IDs (идентификаторами)
last rebootПоказать историю ребутов системы
free -mПоказать количество оставшейся оперативной памяти (-m отображает в мегабайтах)
watch -n.1 'cat /proc/interrupts'Наблюдать последовательно за изменяющимися данными
Информация о системе (см. также sysinfo) (’#’ означает, что для запуска нужны права root-а)
uname -aПоказать версию ядра и системную архитектуру
head -n1 /etc/issueПоказать название и версию дистрибутива (операционной системы)
cat /proc/partitionsПоказать все разделы, зарегистрированные в системе
grep MemTotal /proc/meminfoПоказать всю оперативную память, которую видит система
grep "model name" /proc/cpuinfoПоказать информацию о процессоре(ах) (CPU)
lspci -tvПоказать информацию о шине PCI
lsusb -tvПоказать информацию о USB
mount | column -tСписок смонтированных файловых систем в системе (херархический вывод)
#dmidecode -q | lessОтобразить информацию о SMBIOS/DMI
#smartctl -A /dev/sda | grep Power_On_HoursКакой промежуток времени этот диск (система) был включен (работал)
#hdparm -i /dev/sdaПоказать информацию о диске sda
#hdparm -tT /dev/sdaПротестировать скорость чтения на диске sda
#badblocks -s /dev/sdaПротестировать на нечитаемые блоки диск sda
Интерактивность (см. также горячие клавиши linux)
readlineРедактор строки, используемый bash, python, gnuplot, …
screenВиртуальные терминалы с возможностями открепления, …
mcМощный файл менеджер, которые может просматривать rpm, tar, ftp, ssh, …
gnuplotИнтерактивная (скриптовая) графика
linksТекстовый веб браузер
Разное
alias hd='od -Ax -tx1z -v'Ручной 16-ричный дамп (пример использования: hd /proc/self/cmdline | less)
alias realpath='readlink -f'Канонический путь (пример использования: realpath ~/../$USER)
set | grep $USERПоиск в текущем environment (окружении)

touch -c -t 0304050607 fileУстановить дату для файла (YYMMDDhhmm)
python -m SimpleHTTPServerОтобразить дерево текущего каталога по адресу http://$HOSTNAME:8000/