Настольная книга по Linux/Файлы
В данном разделе рассмотрены примеры работы с файлами (включая обычные файлы, директории, и иные особые файлы) как объектами файловой системы. Примеры по обработке текстового содержания файлов можно найти в разделе Текстовые потоки; взаимодействия с файловыми системами в целом — в разделе Файловые системы.
Создание
[править]Создание нового (пустого) файла filename, или обновление времени последнего изменения если файл существует:
$ touch -- filename
Резервирование пространства на файловой системе под файл filename размером 10 мегабайт (10 × 2²⁰ байт):
$ fallocate -l 10m -- filename
Переносимый (POSIX, BusyBox) вариант:
$ dd bs=1024k count=10 < /dev/zero > filename
Создание заполненного нулевыми байтами файла filename размером 10 мегабайт (10 × 2²⁰ байт) без резервирования пространства на ФС (англ. sparse file):
$ dd bs=1k seek=10239 count=1 < /dev/null > filename
Создание директории dirname; именованного потока («трубы») fifoname; символьной ссылки symname, указывающей на target:
$ mkdir -- dirname $ mkfifo -- fifoname $ ln -s -- target symname
Изменение
[править]Создание нового имени («жесткой ссылки») newname для файла filename:
$ ln -- filename newname $ link -- filename newname
Удаление имени filename; файл будет удален если более не используется (отсутствуют другие имена или ссылки из выполняемых в данный момент процессов):
$ rm -- filename $ unlink -- filename
Переименование файла from в to:
$ mv -- from to
Обратите внимание, что собственно переименование (через системный вызов
rename
) возможно лишь в пределах одной файловой системы.[1] При переименовании между файловыми системами, mv(1) создаст копию to файла from, после чего удалит from.[2]… Файлов file1, file2 в директорию dirname (форма с
--target-directory=
полезна при использовании xargs(1) и опции-exec +
команды find):$ mv -- file1 file2 dirname $ mv --target-directory=dirname -- file1 file2
Замена файла filename пустым; если у файла существуют другие имена (например, созданные командой ln) — они продолжат ссылаться на исходное содержание:
$ mv -f -- "$(mktemp -- ./XXXXX)" filename
… Обнуление содержания; все существующие имена файла будут ссылаться на пустое содержание:
$ true > filename
Права
[править]Разрешить выполнение («запуск») файла ~/bin/newprog (например, после создания программы на Bash, Perl, etc.):
$ chmod -- +x ~/bin/newprog
Изменить режим доступа («права») в директории /my/files, рекурсивно (
-R
), наrw- r-- r--
(644₈) илиrwx r-x r-x
(755₈; где: 4 – чтение, r; 2 – запись, w; 1 – выполнение, x). Бит «исполнимости» будет установлен в том и только том случае, если он уже установлен хотя бы в одном из триплетов.$ chmod -R -- a=rX,u+w /my/files
Изменить права на
rwx r-- --x
(гдеu
— режим доступа для владельца;g
— группы;o
— всех прочих пользователей):$ chmod -R -- u=rwx,g=r,o=x /my/files $ chmod -R -- 741 /my/files
Включить наследование группы для всех вновь создаваемых в директории dirname объектов и разрешить группе запись в данную директорию (и создаваемые объекты):
$ chmod -- g+ws dirname/
Изменить владельца файла filename на user:
# chown -- user filename
… Изменить группу на group:
# chgrp -- group filename # chown -- :group filename
… Изменить владельца на user и группу на group:
# chown -- user:group filename
… Рекурсивно, для директории dirname:
# chown -R -- user:group dirname
Изменить атрибуты Ext2 файла filename — добавить атрибуты
S
(синхронное изменение всех данных на диск, без кэширования),a
(только добавление данных, удаление и переименование запрещено),i
(запрещено удаление, изменение или переименование; англ. immutable):# chattr +Sai filename
Поиск и действия над результатами поиска
[править]
Быстрый поиск подстроки foo по указателю (индексу) имен файлов (обычно — обновляется раз в сутки):
$ mlocate foo $ locate foo
Найти все вхождения строки (
-F
) foo в файлы директории dirname и ее поддиректорий (-r
):$ grep -rF -- foo dirname
… Регулярного выражения (foo|bar).*baz:
$ grep -rE -- '(foo|bar).*baz' dirname
… Только в файлах с именами вида *.[ch]:
$ grep -rE --include='*.[ch]' -- '(foo|bar).*baz' dirname
… Вывести только список файлов (
-l
):$ grep -rlE --include='*.[ch]' -- '(foo|bar).*baz' dirname
Найти все объекты файловой системы в директории dirname и ее поддиректориях:
$ find dirname
… В текущей директории:
$ find
… Только в заданной (текущей) директории — исключая поддиректории:
$ find dirname -maxdepth 1 $ find -maxdepth 1
… Только обычные (англ. regular) файлы:
$ find dirname -type f
… Только обычные файлы, с временем последнего измененения не более 10 дней назад, и с именами, заканчивающимися на
.log
(без учета регистра):$ find dirname -type f -mtime -10 -iname \*.log
Найти в директории dirname обычные файлы с именами вида bak-20??-??-??.tar.gz, состояние которых последний раз изменилось более чем 7 суток назад — кроме имеющих имена вида bak-20??-??-01.tar.gz:
$ find dirname -type f -name 'bak-20??-??-??.tar.gz' \ -ctime +7 -not -name 'bak-20??-??-01.tar.gz'
… И удалить их:
$ find dirname -type f -name 'bak-20??-??-??.tar.gz' \ -ctime +7 -not -name 'bak-20??-??-01.tar.gz' \ -exec rm -- {} +
Удалить все пустые поддиректории dirname, оставаясь в пределах одной файловой системы (
-xdev
; иными словами — игнорируя действующие точки подключения других ФС):$ find dirname -xdev -depth -exec rmdir -- {} + 2> /dev/null
Удалить все поддиректории текущей директории с именами, заканчивающимися на
.svn
без учета регистра (служебные директории Subversion):$ find -type d -iname \*.svn -exec rm -rf -- {} +
Найти в директории dirname (и ее поддиректориях) все обычные файлы с именами, заканчивающимися на
.html
или.htm
, и перекодировать их содержимое в UTF-8 используя enconv(1):$ find dirname \( -name \*.html -o -name \*.htm \) \ -exec enconv -V --convert-to=UTF-8 -- {} +
Обратите внимание, что при перекодировании HTML-файлов также может быть необходимо — отдельным действием — соответственно изменить данные заголовка (
<head />
).Найти в текущей директории (и ее поддиректориях) все обычные файлы с именами, заканчивающимися на
.mp3
(без учета регистра) и перекодировать метаданные из Windows-1251 в UTF-8 используя команду mid3iconv(1) пакетаpython-mutagen
:$ find -iname \*.mp3 -exec mid3iconv -eCP1251 --remove-v1 -- {} +
Tar
[править]
Создать упакованный файловый архив (Tar + XZ) archive.tar.xz из файлов директории dirname:
$ tar -Jc -- dirname > archive.tar.xz $ tar -Jcf archive.tar.xz -- dirname
… Неупакованный архив archive.tar:
$ tar -c -- dirname > archive.tar $ tar -cf archive.tar -- dirname
… Упакованные архивы archive.tar.bz2, archive.tar.gz (упаковщики Bzip2 и Gzip, соответственно):
$ tar -jc -- dirname > archive.tar.bz2 $ tar -zc -- dirname > archive.tar.gz
Распаковать неупакованный архив archive.tar в текущую директорию:
$ tar -x < archive.tar
… Упакованные архивы archive.tar.gz, archive.tar.bz2, archive.tar.xz:
$ tar -zx < archive.tar.gz $ tar -jx < archive.tar.bz2 $ tar -Jx < archive.tar.xz
… В директорию dirname, выводя список файлов по мере распаковки (
-v
):$ tar -C dirname -xv < archive.tar
Создать архив archive.tar.xz из директории dirname удаленной системы remote по SSH:
$ ssh -- remote tar -Jc -- dirname > archive.tar.xz
… Архив archive.tar.xz на удаленной системе remote из директории dirname локальной:
$ tar -Jc -- dirname \ | ssh -- remote cat '>' archive.tar.xz
Распаковать архив archive.tar.xz в директорию dirname удаленной системы remote по SSH:
$ ssh -- remote tar -Jx -C dirname < archive.tar.xz
… Архив archive.tar.xz удаленной системы remote в директорию dirname локальной:
$ ssh -- remote cat '<' archive.tar.xz \ | tar -Jx -C dirname
См. также
[править]- Разделы Текстовые потоки и Файловые системы.