Почему нет команды оболочки для создания файлов?

27

Внимание, пожалуйста:

Я не спрашиваю, как сделать файл из командной строки!


Я использовал touchдля создания файлов в течение многих лет, не обращая внимания на то, что его основная цель заключается в другом. Если кто-то хочет создать файл из командной строки, существует так много возможностей:

touch foo.bar
> foo.bar
cat > foo.bar
echo -n > foo.bar
printf '' > foo.bar

И я уверен, что есть еще.

Но дело в том, что ни одна из приведенных выше команд не предназначена для создания файлов. Например, man touchпредполагает , что эта команда предназначена для изменения временных меток файла. Почему в операционной системе, такой как Unix (или Linux), нет команды, предназначенной исключительно для создания файлов?

Pouya
источник
35
Зачем вам загромождать систему, чтобы добавить команду для выполнения чего-то, что можно сделать дюжиной способов с помощью уже существующих инструментов?
Майкл Кохне
4
Почему нет команды для чтения файлов из / в streams / stdin / out? Каждый использует команду, предназначенную для catразговора!
SF.
2
@MichaelKohne, я вижу вашу точку зрения, при всем моем уважении, у меня есть проблема с ней. При таком подходе существует много команд, которые только загромождают систему. Зачем использовать, moreкогда lessделает больше, чем moreделать? Или dirи ls. Хотя я знаю о проблемах совместимости.
Pouya
9
moreпредшествует созданию less. lessбыл создан специально для устранения недостатков more. moreвсе еще существует по причинам обратной совместимости. dirи ls, для большинства намерений и целей, являются одним и тем же исполняемым файлом - они отличаются только несколькими байтами. Новый инструмент , предназначенный специально для создания файлов будет делать меньше , чем существующие инструменты, и, таким образом, было бы регресс, а не улучшение , как и в случае lessпротив more.
Ланц
1
Кроме того, нам нужно взглянуть на наследие, Unix был создан при подсчете каждого байта. Зачем создавать утилиту для задачи, которую вы можете выполнять с уже существующей утилитой?
Томас,

Ответы:

38

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

Совершенно бесполезно сначала создавать файл, а затем использовать перенаправление ввода / вывода для записи в файл, если вы можете сделать это за один шаг.

В тех случаях, когда вы действительно хотите создать пустой файл и оставить его, я бы сказал, что это > "${file}"не может быть более коротким и элегантным.

TL; DR : его не существует, потому что создание пустых файлов чаще всего бесполезно, и в тех случаях, когда оно есть, уже есть множество вариантов, доступных для достижения этой цели.

С другой стороны, использование touchработает только в том случае, если файл не существует, тогда как параметры, использующие перенаправление, всегда будут обрезать файл, даже если он существует (так что технически эти решения не идентичны). > fooявляется предпочтительным методом, поскольку он экономит, forkи его echo -nследует избегать в целом, так как он очень непереносим.

Адриан Фрювирт
источник
1
Я нашел вашу точку зрения о создании файла и затем использовании инструментов ввода / вывода, очень твердым. Спасибо.
Pouya
1
@FaheemMitha Да ( >>). Я имел в виду примеры, приведенные OP с использованием >. Добавление будет бесполезным, если вы создаете файлы (или NOOP, если они существуют).
Адриан Фрювирт,
1
Не забывайте, что noclobberэто не нужно устанавливать, чтобы >перезаписать существующий файл.
Ouki
1
@Ouki AFAIK, настройка, которая не является поведением по умолчанию, и можно забыть, что она установлена ​​в одной системе, а не в другой, что потенциально может привести к проблемам так же, как создание alias rm='rm -i'вместо alias rmi='rm -i'- плохая идея.
Agi Hammerthief
1
@mikeserv, только > .fileв командной строке, сделает это без проблем :.
Чарльз Даффи
16

Ответ Адриана Фрювирта правильный. Я просто хотел бы добавить , что есть на самом деле команда специально написано для создания файлов: mktemp.

NAME
       mktemp - create a temporary file or directory

SYNOPSIS
       mktemp [OPTION]... [TEMPLATE]

DESCRIPTION
       Create a temporary file or directory, safely, and print its name.  TEM
       PLATE must contain at least 3 consecutive 'X's in last  component.   If
       TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.
       Files are created u+rw, and directories  u+rwx,  minus  umask  restric
       tions.

Конечно, mktempзадача не в том, чтобы создать файл с определенным именем, а в том, чтобы просто создать файл . Однако, как вы уже сказали, существует множество более эффективных и элегантных способов создания файлов с заданным именем, поэтому указание команды для этого было бы бессмысленным.

Тем не менее, у вас также есть, truncateи fallocateоба из которых основной целью является создание файлов. У них просто более сложный подход. Никогда не будет простой программы, которая делает то, что > fileделает, потому что нет способа, которым она будет лучше, чем > file.

Тердон
источник
11

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

: >./file

Это создает пустой файл. Или обрезает существующий файл, как вы хотите. Вы можете:

set -o noclobber

чтобы избежать любой возможности в последнем случае, если вы:

: >|./file

Вы можете получить похожее поведение touchс:

: >>./file
: >>|./file

За исключением того, что :не будет обновлять мод времени файла, потому что он не изменен.

DEMO

mkdir test ; cd $_
touch touch.file 
: >null.file
echo >echo.file
ls -l

ВЫХОД

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file

НЕ ТРОГАТЬ

: >>|./echo.file
ls -l 

ВЫХОД

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file
mikeserv
источник
По умолчанию эхо добавляется \nв конце строки. Попробуйте echo -n >echo-n.file(размер = 0) и echo -e >echo-e.file(размер = 1)
Томас,
@Thomas 'Строка для записи в стандартный вывод. Если первый операнд -n, или если любой из операндов содержит символ обратной косой черты ('\'), результаты определяются реализацией. В XSI-совместимых системах, если первый операнд -n, он должен рассматриваться как строка, а не как опция. Следующие последовательности символов должны быть распознаны в XSI-совместимых системах в любом из аргументов ... ' pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
mikeserv
Справедливо, спасибо за ссылку, и мой комментарий не имеет значения в любом случае
Томас
2
Да, действительно, и извините, я имел в виду, что в моем комментарии все равно не хватает смысла вашего ответа, извините за это.
Томас,
1
Иллюстрацией тенденции Unix к обобщению является тот факт, что вызывается команда для отображения содержимого файла cat. Зачем нужна команда для отображения одного файла, если вы можете сделать одну команду для объединения нескольких файлов в стандартный вывод?
200_success
1

Утилита installна самом деле предназначена для создания файлов! Вы можете передать содержимое файла через /dev/stdin(но в большинстве случаев, однако, в большинстве версий Linux это требует /procмонтирования) или предоставить другой исходный файл. Вы можете установить владельца и разрешения.

echo "New file" | install -o 0644 -m 452452 -g dumbass /dev/stdin /var/www/index.html

как глупый пример.

Otheus
источник