Полезности для работающих в командной строке *nix

Материал из RSU WiKi
Перейти к: навигация, поиск
Tower of babel.png外國 language!
В статье используется несколько языков. Необходимо использовать один. Совсем неплохо, если это будет русский.

Содержание

Генерация паролей и случайных строк

Способ №1

Для быстрой генерации пароля или "соли" для cookie-файлов, можно воспользоваться командой[1]:

cat /dev/urandom| tr -dc 'a-zA-Z0-9' | fold -w 10| head -n 4

Она выдает 4 строки по 10 символов (без спец. символов).

Способ №2

dd if=/dev/urandom bs=6 count=1|base64

Способ №3

cat /dev/[u]random | uuencode -m - | head -n 2 | tail - -c длина пароля

Быстро сделать резервную копию конф. файла перед редактированием

cp <filename>{,.`date +%Y-%m-%d`}

Рекурсивно 755/644 на каталоги и файлы

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

Способ №1 (самый быстрый)

chmod -R a-x+rX directory/

Способ №2

Работает медленнее способа 1 и быстрее способа 3

find /path -type d -print0 | xargs -0 chmod 0755
find /path -type f -print0 | xargs -0 chmod 0644

Способ №3

find /path -type d -exec chmod 0755 "{}" ";"
find /path -type f -exec chmod 0644 "{}" ";"

Вывод всех поддиректорий с размерами

Способ №1

du -lh --max-depth=1

Способ №2

find . -maxdepth 1 -type d -exec du -sk {} \; | sort -rn

Способ №3

find . -maxdepth 1 -type d -print | xargs du -sh | sort -rn

Удаляем из файла все пустые строки

grep -v "^$" filename > newfilename

Разбиваем переменную на имя файла и расширение

Вариант 1 [2]:

~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz

Вариант 2:

filename=$(basename "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"

Вариант 3:

#!/bin/bash
for fullpath in "$@"
do
    filename="${fullpath##*/}"                      # Strip longest match of */ from start
    dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename
    base="${filename%.[^.]*}"                       # Strip shortest match of . plus at least one non-dot char from end
    ext="${filename:${#base} + 1}"                  # Substring from len of base thru end
    if [[ -z "$base" && -n "$ext" ]]; then          # If we have an extension and no base, it's really the base
        base=".$ext"
        ext=""
    fi
 
    echo -e "$fullpath:\n\tdir  = \"$dir\"\n\tbase = \"$base\"\n\text  = \"$ext\""
done

Вариант 4:

basename filename .extension

Обнуление файла

:>file

То же, что и

cat /dev/null > file

Просмотр файла без комментариев и пустых строк

egrep -v "^#|^[:blank:]*$" file

или, проще

egrep -v "^#|^$" file

Особенно удобно для просмотра конфигов.


for x in *; do mv "$x" `echo $x | sed -e 's/ /_/g'`; done

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

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

Вместо БЫЛО и СТАЛО нужно поставить правила регулярных выражений, а вместо echo - когда убедитесь, что делает что надо, поставить mv, "to" убрать совсем - в mv он, конечно, не нужен.

for x in *; do OLDFILE=$x; NEWFILE=`echo $x | perl -i -npe "s/БЫЛО/СТАЛО/ig";`;echo $OLDFILE to $NEWFILE; done

Добавление в начало имен файлов, перечисленных в комадной строке даты и времени

#!/bin/bash
 
while [ -e "$1" ]
do
 NEW=`date -r "$1" +%Y-%m-%d_%Hh%M`
 echo "$1 -> "$NEW"_"$1
# mv "$1" $NEW"_$1"
 shift
done

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

Замена подстроки в нескольких файлах

sed -i 's/А. Эйнштейн/Альберт Эйнштейн/g' ./*

Удаляем в каталоге все файлы кроме указанных

rm !(file1|file2|)

Дать группе пользователи права записи во все существующие и вновь создаваемые подкаталоги конкретной директории (Posix ACL)

setfacl -R -m g:users:w dir/

Указываем AWK, что в строке несколько разделителей колонок

В примере «пробел» и «#»:

awk -F "[\ #] "'{ print $7 }' < our_file

Сортируем файл по второму столбцу

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

sort -n -k 2 -r

Просто найти файл

find / -type f -name "myfile" -print

Заменяем любое количество табов (\t) в текстовом файле на один

sed -e 's/\t[\t]*/\t/g' inputFile

Выбираем из строк только содержимое "в кавычках"

grep -o '\"[A-Z0-9\-]*\"' < inputFile

Убираем "\r"...

...в файле

tr -d "\r" < file.DOS > file.UNIX

...во всех файлах в директории

sed -i -re 's/\x0d//g' *.txt

...во всех директориях и поддиректориях

find /path/to/dir -type f | while read i; do perl -pe 's/\r//g' -i "$i"; done

Конвертируем все html-файлы в текущей папке и ее подпапках из кодировки CP1251 в UTF-8 с удалением символов перевода каретки (\r)

#!/bin/bash
 
for i in `find ./ -name "*.html"`
 do
  tr -d "\r" < $i > $i.tr
  iconv -f cp1251 -t utf-8 < $i.tr > $i.utf
  rm $i $i.tr
  mv $i.utf $i
 done

Примонтируем одну папку в другую (полезно для FTP-серверов, которые не работают с симлинками)

mount --bind /foo /home/fred/foo

Строчка для fstab (автоподмонтирование при загрузке системы):

/foo    /home/fred/foo    auto      bind 0 0

Закачиваем локальный файл в каталог на удаленном ftp-сервере

ftp -u ftp://ftp.cexample.com/incoming/ LocalFilename.gz

Дополнения в адресах хостов, с которыми вы соединяетесь через ssh

Для тех, кто часто использует терминал и ssh данная хитрость буде весьма удобна. Добавьте следующую строчку в ваш файл .bash_profile:

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh

Это добавит возможность дополнения в адресах хостов, с которыми вы соединяетесь через ssh. Хосты берутся из файла ~/.ssh/known_hosts.

Настройка Sudo: убираем пароль для определенных команд (nopasswd)

Sudo (Super User Do) консольная утилита в Linux, дающая пользователям возможность выполнения программ с правами администратора без знания его пароля. В Интернете есть очень много статей на тему, почему sudo популярна, там вы сможете найти множество подсказок , как настроить sudo чтобы исполнять программы, требующие права администратора, без использования паролей. Существует несколько способов настройки sudo в Linux, независимо от используемого дистрибутива. Файл настроек находится в /etc/sudoers и может быть изменен любым текстовым редактором vi, nano, pico, gedit, mcedit, например:

sudo vi /etc/sudoers

или

sudo visudo

Итак, чтобы разрешить пользователю, например, testuser исполнять, например, команду ifconfig и присваивать IP адреса, маску подсети к интерфейсу, добавьте строчку в /etc/sudoers:

artemn ALL = PASSWD: ALL, NOPASSWD: /sbin/ifconfig

Пожалуйста, проверьте не добавлена ли эта строчка уже для пользователя testuser в файле sudoers, просто замените ее [3].

Быстрая передача файла через псевдо-HTTP

Когда есть необходимость передать файл с одной машины на другую, а под рукой нет общедоступных ресурсов, можно сделать так:

nc -l -p 8080 < file

или

netcat -l 8080 < file

на клиенте достаточно в браузере набрать http://192.168.0.123:8080

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

(echo -e "HTTP/1.1 200\nContent-Disposition: attachment; 
filename=gena_na.png\nContent-Type: application/octet-
stream\nConnection: close\n"; cat vim_mrxvt.png ) | nc -vv -l -p 8080

Но это еще не все. Можно дать доступ к целой директории, написав простой HTTP сервер в одной строке:

while true; do nc -vv -l -p 8080 -c '( read a b c; file=`echo $b | sed 's/[^a-z0-9.]//g'`; 
if [ a$file = "a" ]; then ( ls | (while read f; do echo "<a href=$f>$f</a><br>"; done) ); 
else cat $PWD/$file; fi )'; sleep 1; done

Этот скрипт отдает все файлы, которые есть в текущем каталоге и не позволяет его сменить. В случае, если запрашивается корневая директория, то управление передается своеобразному mod_index - т.е. выводится список файлов-ссылок. В конце добавлена задержка в 1 сек для того, чтобы была возможность убить его нажатием Ctrl-C.

См. подробнее http://connection-refused.blogspot.com/2006/12/http-222.html

Cron

*     *     *   *    *        command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0 - 6) (Sunday=0)
|     |     |   +------- month (1 - 12)
|     |     +--------- day of        month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)

Полезные примеры:

How can I execute `date` inside of a cron tab job?

Q: I want to create a log file for a cron script that has the current hour in the log file name. This is the command I tried to use:

0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+%d"`.log

Unfortunately I get this message when that runs:

/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file

I have tried escaping the date part in various ways, but without much luck. Is it possible to make this happen in-line in a crontab file or do I need to create a shell script to do this?

Short answer:

Try this:

0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+\%d"`.log

Note the backslash escaping the % sign.

Long answer:

The error message suggests that the shell which executes your command doesn't see the second back tick character:

/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'

This is also confirmed by the second error message your received when you tried one of the other answers:

/bin/sh: -c: line 0: unexpected EOF while looking for matching `)'

The crontab manpage confirms that the command is read only up to the first unescaped % sign:

The "sixth" field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the cronfile. Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline charac- ters, and all data after the first % will be sent to the command as standard input [4] [5].

Как перекинуть по сети ВСЕ, если нет НИЧЕГО

нужен только netcat, аццкий многофункциональный "перочинный нож", который есть в любой UNIX-системе. Итак, берем netcat. на стороне, с которой хотим стянуть информацию пишем в терминале:

tar -c ./*| netcat somehost.somedomain 10000 -v

на принимающей стороне, собственно тоже пишем:

netcat -l -p 10000 -v| tar -x ./

Вот :)

Удаляем ".svn" из дерева каталогов

find . -name ".svn" -type d -exec rm -rf {} \;

Узнаем размер RAM в Linux

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

awk '{if(/MemTotal/){if($3=="kB"){$2/=1024;$3="MB"}; printf("%d\n",$2 + 0.5)}}' /proc/meminfo

UNZIP

Чтобы разархивировать множество zip файлов в каталоге необходимо набрать в консоли:

unzip \*.zip

Если же набрать

unzip *.zip

то возникнет ошибка

caution: filename not matched:

Удаленные, но занимающие место файлы

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

lsof | grep deleted

zombie процессы

 ps -el | grep 'Z'

Удаляем повторяющиеся строки с помощью uniq

Основная статья: Remove duplicate lines with uniq

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

rsync -r -v --include '*/' --include '*.php' --exclude '*' sourcedir targetdir

Отправляем каталог на удаленный сервер по SSH с компрессией

rsync -avz -e ""ssh -l ssh-username" /path/to/local/dir 192.0.2.99:/path/to/remote/dir/

Кто съел всю память на хосте?

ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS

Кто слушает порт на локальной машине?

netstat -tulpn

via http://www.cyberciti.biz/faq/what-process-has-open-linux-port/

Bash command to sum a column of numbers

Способ I

Using existing file [6]:

paste -sd+ infile | bc

Using stdin:

<cmd> | paste -sd+ | bc

Edit: With some paste implementations you need to be more explicit when reading from stdin:

<cmd> | paste -sd+ - | bc

Способ II

<cmd> | awk '{ sum+=$1} END {print sum}'

Разное

cat pravo.txt pravo.txt | sort | grep -v "^$" | sed 'n;G;'| sed "s/^$/123/" > pravo2.txt

Конвертирование картинки в чёрно-белую картинку качества факсового документа

XX% - порог в процентах, вычисляется экспериментально

convert <input>.jpg -type Grayscale -threshold XX% <output>.png

Подсчет количества ПК в университетских DNS-зонах

Мы имеем:

  1. Все зоны заканчиваются на rspu.
  2. В прямой зоне записи компьютеров от служебной информации отличаются наличием разделителя IN A.
  3. Типовое имя ПК: bXaYtZ или bXaYeZ, где Z от 00 до 99 с ведущими нулями.
cat *rspu | grep "IN A" | grep '[te][0-9][0-9]' -c

Multiple expression if statement in BASH

It’s not very well documented, but it’s possible to include multiple conditional expressions in a single if statement in BASH. By multiple conditional expressions, I mean something like:

if foo = 1 or bar = 3 or abc = 4 then
    print Hello World
end if

You can do boolean OR in BASH by using the -o operator. The following is the above code written in BASH:

if [ $foo -eq 1 -o $bar -eq 3 -o $abc -eq 4 ]; then
    echo Hello World
fi

For boolean AND, use the -a operator. You can also intermix the two.

7 способов улучшить ваши shell скрипты на /bin/sh

Несколько приемов для того, чтоб сделать свои скрипты компактнее, быстрее и правильней:

Упрощение конструкции с if

Конструкцию

if команда1
then
    команда2
fi

можно заменить просто на

команда1 && команда2

Упрощение конструкции с if !

Конструкцию

if ! команда1
then
    команда2
fi

можно заменить просто на

команда1 || команда2

Если вы используете шаблоны или подстановку аргументов в shell

Если вы используете шаблоны (скажем, *) или подстановку аргументов в shell при помощи ``, то если их много shell не может сделать такую подстановку. Тогда стоит прибегнуть к помощи команды xargs.

Т.е. строчка

rm * 

в директории, которая содержит слишком много файлов, может превратиться в

ls | xargs rm

Или же

rm `find ./ -name pkg-descr`

может превратиться в

find ./ -name pkg-descr | xargs rm

Ускорить grep

Если вы ищите какую-то строку в больший объемах данных при помощи grep, то стоит использовать fgrep — который позволяет искать только вхождения строк, а не регулярных выражений — но и работает быстрее на 10-20%.

Пишем условия правильно

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

if [ $INPUT = test ]; then ... fi

то стоит применять либо вариант с дописыванием одного символа с обоих сторон сравнения

if [ x$INPUT = xtest ]; then ... fi

либо брать переменную в двойные кавычки

if [ "$INPUT" = test ]; then ... fi

Чтоб не дать команде выводить что-либо на экран

Можно использовать перенаправление стандартного вывода и стандартного потока ошибок в /dev/null

ping -c foo.bar > /dev/null 2>/dev/null

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

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

Если вы из скрипта хотите отослать сигнал завершения или какой-либо другой группе команд и используете для этого строчку типа

kill -9 `ps -ax | grep PROCESS_NAME | cut -c1-5 `

то вы случайно можете убить и процесс grep и получить неправильные результаты. Поэтому обязательно переписывайте такие команды вот так:

kill -9 `ps -ax | grep PROCESS_NAME | grep -v grep | cut -c1-5`

Это исключит саму команду grep из списка убиваемых процессов.

Примечания

  1. Linux: Generating Strong Passwords Using random/urandom
  2. http://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
  3. http://www.linuxscrew.com/2008/06/22/configure-sudo-nopasswd/#ixzz1bOIFXc7K
  4. How can I execute `date` inside of a cron tab job?
  5. Using the system date / time in a Cron Script
  6. stackoverflow.com Bash command to sum a column of numbers

См. также

Ссылки

Личные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты