Выбрать главу

# 2) && "И-список": благодаря этому все последующие команды будут выполнены

# только тогда, когда 'cd' завершится успешно

# 3) tar cf - . ключом 'c' архиватор 'tar' создает новый архив,

# ключом 'f' (file) и последующим '-' задается файл архива -- stdout,

# в архив помещается текущий каталог ('.') с вложенными подкаталогами.

# 4) | конвейер с ...

# 5) ( ... ) subshell-ом (дочерним экземпляром командной оболочки)

# 6) cd /dest/directory Переход в каталог назначения.

# 7) && "И-список", см. выше

# 8) tar xpvf - Разархивирование ('x'), с сохранением атрибутов "владельца" и прав доступа ('p') к файлам,

# с выдачей более подробных сообщений на stdout ('v'),

# файл архива -- stdin ('f' с последующим '-').

#

# Примечательно, что 'x' -- это команда, а 'p', 'v' и 'f' -- ключи

# Во как!

# Более элегантный вариант:

# cd source-directory

# tar cf - . | (cd ../target-directory; tar xzf -)

#

# cp -a /source/directory /dest имеет тот же эффект.

bunzip2 linux-2.4.3.tar.bz2 | tar xvf -

# --разархивирование tar-файла-- | --затем файл передается утилите "tar"--

# Если у вас утилита "tar" не поддерживает работу с "bunzip2",

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

# Целью данного примера является разархивирование тарбола (tar.bz2) с исходными текстами ядра.

Обратите внимание, что в этом контексте "-" - не самостоятельный оператор Bash, а скорее опция, распознаваемая некоторыми утилитами UNIX (такими как tar, cat и т.п.), которые выводят результаты своей работы в stdout.

bash$ echo "whatever" | cat -

whatever

В случае, когда ожидается имя файла, тогда "-" перенаправляет вывод на stdout (вспомните пример с tar cf) или принимает ввод с stdin.

bash$ file

Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file...

Сама по себе команда file без параметров завершается с сообщением об ошибке.

Добавим символ "-" и получим более полезный результат. Это заставит командный интерпретатор ожидать ввода от пользователя.

bash$ file -

abc

standard input: ASCII text

bash$ file -

#!/bin/bash

standard input: Bourne-Again shell script text executable

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

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

С помощью команды diff -- находить различия между одним файлом и частью другого:

grep Linux file1 | diff file2 -

И наконец пример использования служебного символа "-" с командой tar.

Пример 3-4. Резервное архивирование всех файлов, которые были изменены в течение последних суток

#!/bin/bash

# Резервное архивирование (backup) всех файлов в текущем каталоге,

# которые были изменены в течение последних 24 часов

#+ в тарболл (tarball) (.tar.gz - файл).

BACKUPFILE=backup

archive=${1:-$BACKUPFILE}

# На случай, если имя архива в командной строке не задано,

#+ т.е. по-умолчанию имя архива -- "backup.tar.gz"

tar cvf - `find . -mtime -1 -type f -print` > $archive.tar

gzip $archive.tar

echo "Каталог $PWD заархивирован в файл \"$archive.tar.gz\"."

# Stephane Chazelas заметил, что вышеприведенный код будет "падать"

#+ если будет найдено слишком много файлов

#+ или если имена файлов будут содержать символы пробела.

# Им предложен альтернативный код:

# -------------------------------------------------------------------

# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"

# используется версия GNU утилиты "find".

# find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;

# более универсальный вариант, хотя и более медленный,

# зато может использоваться в других версиях UNIX.

# -------------------------------------------------------------------

exit 0