ServerAID
Найти гайд, команду, тег… ⌘ K
Shell и скрипты

Как создать файл в Linux через терминал: touch, перенаправление, tee и heredoc

Пустой файл, файл с текстом, файл сразу с нужными правами, файл заданного размера, сотня файлов одной командой — в терминале Linux под каждую задачу есть своя короткая команда. Разбираем touch, операторы > и >>, cat, tee для файлов от root и heredoc для многострочных конфигов.

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

touch — пустой файл

Самый короткий способ:

touch report.txt

Если файла не было, появится пустой. Если файл уже есть, touch его не тронет — только обновит время последнего доступа и изменения. Это, кстати, его основное назначение: имя произошло от «прикоснуться».

Несколько файлов сразу:

touch app.log error.log access.log

Файл в другом каталоге — обычным путём:

touch /var/tmp/test.txt
touch ~/documents/notes.md

Каталогов touch не создаёт: если ~/documents не существует, команда вернёт No such file or directory. Сначала каталог:

mkdir -p ~/documents && touch ~/documents/notes.md

Флаг -p создаёт всю цепочку вложенных каталогов и не ругается, если они уже есть.

Полезный флаг -c — не создавать файл, если его нет, а только обновить время существующего:

touch -c maybe-exists.txt

Оператор > — файл с содержимым

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

echo "server 1 ok" > status.txt

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

Дописывание в конец — двойная стрелка:

echo "server 2 ok" >> status.txt

Совсем пустой файл через перенаправление:

> empty.txt

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

> /var/log/myapp.log

Именно обнуление, а не удаление: приложение продолжает писать в тот же дескриптор. Если лог удалить командой rm, место на диске не освободится, пока процесс не перезапустят.

Защита от случайной перезаписи включается опцией noclobber:

set -o noclobber
echo test > status.txt      # cannot overwrite existing file
echo test >| status.txt     # принудительно, в обход защиты

Записываем вывод любой команды

Справа от > может стоять что угодно:

ls -la /etc > etc-listing.txt
df -h > disk-usage.txt
ps aux > processes.txt

Ошибки при этом в файл не попадают — они идут в отдельный поток stderr и остаются на экране. Чтобы сохранить и их:

command > out.txt 2>&1        # оба потока в один файл
command > out.txt 2> err.txt  # раздельно

Конструкция 2>&1 означает «направить поток 2 (stderr) туда же, куда уже направлен поток 1 (stdout)». Порядок важен: 2>&1 > out.txt сработает не так, как ожидается, — на момент разбора stdout ещё указывает на терминал.

cat и heredoc — многострочный файл

Для файла в несколько строк удобен cat с перенаправлением:

cat > notes.txt

Терминал ждёт ввод. Печатаете строки, завершаете Ctrl+D на пустой строке. Прервать без сохранения — Ctrl+C.

В скриптах используют heredoc — блок текста прямо в коде:

cat > /tmp/app.conf <<'EOF'
host = 127.0.0.1
port = 8080
debug = false
EOF

Кавычки вокруг EOF принципиальны. С кавычками (<<'EOF') текст пишется как есть. Без кавычек bash подставит внутри переменные и выполнит команды в обратных кавычках:

NAME=prod
cat > /tmp/info.txt <<EOF
environment: $NAME
generated: $(date +%F)
EOF

В первом случае в файл попадёт буквально $NAME, во втором — prod. Для конфигов с символом $ (например, nginx с $uri) всегда берите вариант с кавычками, иначе bash съест переменные.

tee — файл от имени root

Классическая ловушка: команда с sudo, а перенаправление всё равно падает с Permission denied.

sudo echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-custom.conf
# bash: /etc/sysctl.d/99-custom.conf: Permission denied

Причина в том, что перенаправление выполняет шелл, а он работает от обычного пользователя. sudo повышает права только для echo, но файл открывает не он. Подробнее про механику — в статье про sudo.

Правильный способ — tee, который сам получает права root:

echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-custom.conf

tee пишет в файл и дублирует ввод на экран. Если вывод не нужен, глушим его:

echo "..." | sudo tee /etc/nginx/conf.d/custom.conf > /dev/null

Дописать в конец — флаг -a (аналог >>):

echo "10.0.0.5 db-server" | sudo tee -a /etc/hosts

Heredoc с tee — стандартный способ создавать конфиги в скриптах:

sudo tee /etc/systemd/system/myapp.service > /dev/null <<'EOF'
[Unit]
Description=My App

[Service]
ExecStart=/usr/local/bin/myapp

[Install]
WantedBy=multi-user.target
EOF

Что делать с этим юнитом дальше — в статье про systemd и systemctl enable.

Файл сразу с нужными правами

Обычно права выставляют вторым шагом через chmod. Но install умеет создавать файл сразу с правами и владельцем:

sudo install -m 600 -o www-data -g www-data /dev/null /var/www/.secret

Это важно для файлов с паролями: между touch и chmod 600 есть короткое окно, когда файл доступен всем на чтение. install такого окна не оставляет. Подробнее о числах в правах — в разборе chmod, о владельцах — в статье про chown.

Права по умолчанию для новых файлов задаёт umask:

umask          # обычно 0022
touch new.txt
ls -l new.txt  # -rw-r--r--

Маска вычитается из базовых прав 666 для файлов: 666 − 022 = 644, то есть -rw-r--r--. Установить строже на текущую сессию:

umask 077
touch private.txt
ls -l private.txt   # -rw-------

Файл заданного размера

Для тестов скорости диска или проверки квот нужен файл конкретного объёма.

Мгновенно, без записи данных (разрежённый файл):

truncate -s 1G bigfile.img

Файл показывает размер 1 ГБ, но места на диске почти не занимает — реальные блоки выделятся при записи. Проверить: du -h bigfile.img покажет почти ноль, а ls -lh — гигабайт.

С реальным выделением места:

fallocate -l 1G swapfile.img

Именно так создают файл подкачки — про это подробно в статье про swap.

С реальной записью данных (медленно, но подходит для замера скорости):

dd if=/dev/zero of=test.img bs=1M count=1024 status=progress

Файл со случайным содержимым:

head -c 10M /dev/urandom > random.bin

Много файлов одной командой

Фигурные скобки раскрываются шеллом до запуска команды:

touch file{1..10}.txt          # file1.txt ... file10.txt
touch report-{jan,feb,mar}.csv # три файла с именами месяцев
touch log{01..12}.txt          # с ведущим нулём: log01 ... log12

Комбинации перемножаются:

touch {app,db}-{dev,prod}.conf
# app-dev.conf app-prod.conf db-dev.conf db-prod.conf

Проверить, что раскроется, до выполнения — через echo:

echo {app,db}-{dev,prod}.conf

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

Создать структуру каталогов и файлы в ней:

mkdir -p project/{src,tests,docs}
touch project/{src,tests}/main.py

Временные файлы

Для скриптов создавать временный файл со случайным именем правильнее через mktemp — он гарантирует уникальность и права 600:

tmpfile=$(mktemp)
echo "данные" > "$tmpfile"
# ... работа ...
rm -f "$tmpfile"

Временный каталог:

tmpdir=$(mktemp -d)

Надёжная уборка даже при ошибке — через trap:

tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT

Фиксированное имя вроде /tmp/mytemp.txt в общедоступном /tmp — небезопасно: другой процесс может подсунуть на это имя симлинк.

Проверяем, что получилось

ls -l notes.txt      # права, владелец, размер, дата
stat notes.txt       # подробно: inode, все три метки времени
file notes.txt       # тип содержимого
wc -l notes.txt      # количество строк
cat notes.txt        # содержимое целиком
head -20 notes.txt   # первые 20 строк

stat показывает три метки времени: Access (последнее чтение), Modify (изменение содержимого), Change (изменение метаданных — прав, владельца). touch без флагов обновляет первые две.

Частые вопросы

Как создать файл в Linux одной командой?

Пустой — touch имя_файла. Сразу с текстом — echo "текст" > имя_файла.

Если файл уже существует, touch его не изменит, а > перезапишет содержимое без предупреждения. Для дописывания в конец используйте >>.

Почему sudo echo > /etc/file выдаёт Permission denied?

Перенаправление > выполняет шелл, а не команда после sudo. Шелл работает от обычного пользователя, поэтому файл в /etc открыть не может — повышение прав до него не доходит.

Решение — tee, который сам запускается под sudo: echo "текст" | sudo tee /etc/file. Для дописывания — sudo tee -a.

Как создать файл с несколькими строками текста?

Через heredoc: cat > file.txt <<'EOF', затем строки, затем EOF на отдельной строке. Кавычки вокруг EOF отключают подстановку переменных — для конфигов с символом $ это обязательно.

Интерактивно можно и без heredoc: cat > file.txt, ввести текст, завершить Ctrl+D.

Чем touch отличается от > при создании файла?

touch создаёт файл, только если его нет, и никогда не трогает содержимое существующего — обновляет лишь метки времени. Оператор > создаёт файл или полностью очищает уже существующий.

Поэтому touch безопаснее для «убедиться, что файл есть», а > подходит, когда нужно начать с чистого листа.

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

Через раскрытие фигурных скобок: touch file{1..100}.txt создаст сто файлов. Списком: touch {app,db,web}.conf.

Перед запуском проверьте раскрытие командой echo вместо touch — увидите точный список имён до того, как что-то создастся.

Что запомнить

  • touch — пустой файл, не трогает существующий; > — создаёт или полностью перезаписывает; >> — дописывает в конец.
  • sudo echo > /etc/файл не работает никогда: перенаправление делает шелл. Нужен sudo tee.
  • Heredoc <<'EOF' с кавычками пишет текст буквально, без кавычек — подставляет переменные и результаты команд.
  • Файлы с секретами создавайте через install -m 600, а не парой touch + chmod — иначе есть окно, когда файл читают все.
  • truncate создаёт файл-пустышку мгновенно, fallocate реально выделяет место, dd записывает данные.

Похожие материалы

Shell и скрипты

Как распаковать tar.gz в Linux через терминал: tar, zip, xz и другие форматы

Короткий ответ — tar -xzf archive.tar.gz. Дальше разбираем, что означает каждая буква, как распаковать в нужный каталог, посмотреть содержимое до распаковки, вытащить один файл из большого архива и не поймать «tar-бомбу», которая раскидает сотни файлов по текущему каталогу.

Редакция
Shell и скрипты

Команда lsblk в Linux: как посмотреть диски, разделы и точки монтирования

lsblk показывает все блочные устройства сервера деревом: диски, разделы, LVM-тома, шифрованные контейнеры и куда они смонтированы. Разбираем колонки вывода, флаг -f для файловых систем и UUID, свои наборы колонок через -o и типовые задачи — найти новый диск, собрать строку для fstab, понять структуру LVM.

Редакция
Shell и скрипты

Команды vi в Linux: режимы, навигация, поиск и замена — шпаргалка

Начнём с главного: выйти из vi — это Esc, затем :q! без сохранения или :wq с сохранением. Дальше — рабочий минимум команд, которого хватает для правки конфигов на сервере: режимы, перемещение, удаление и вставка, поиск с заменой и трюк для сохранения файла, который открыли без sudo.

Редакция
Shell и скрипты

Как скопировать файл в Linux через терминал: cp, rsync и scp с примерами

Разбираем копирование в терминале: cp для файлов и каталогов, флаг -a для сохранения прав и симлинков, rsync для больших объёмов и докачки, scp для переноса на другой сервер. Плюс ловушки со слэшем в конце пути и скрытыми файлами, на которых теряют данные.

Редакция