Dlaczego nie ma żadnego polecenia powłoki do tworzenia plików?

27

Proszę o uwagę:

Ja nie pytając, jak zrobić plik z wiersza poleceń!


Używam touchdo tworzenia plików od lat, nie zwracając uwagi, że jego głównym celem jest coś innego. Jeśli chcesz utworzyć plik z wiersza poleceń, istnieje wiele możliwości:

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

I jestem pewien, że jest ich więcej.

Ale w rzeczywistości żadne z powyższych poleceń nie jest przeznaczone do tworzenia plików. Na przykład man touchsugeruje , że to polecenie służy do zmiany znaczników czasu pliku. Dlaczego system operacyjny tak kompletny jak Unix (lub Linux) nie ma polecenia przeznaczonego wyłącznie do tworzenia plików?

Pouja
źródło
35
Dlaczego zaśmiecasz system, aby dodać polecenie, aby zrobić coś, co można zrobić na kilkanaście sposobów za pomocą narzędzi, które już istnieją?
Michael Kohne
4
Dlaczego nie ma polecenia do odczytu plików z / do strumieni / stdin / out? Wszyscy używają polecenia przeznaczonego do catkoneksji!
SF.
2
@MichaelKohne, rozumiem o co ci chodzi, z całym szacunkiem, mam z tym problem. Przy takim podejściu istnieje wiele poleceń, które jedynie zaśmiecają system. Po co korzystać, morekiedy lessrobi więcej niż to more! Lub diri ls. Chociaż zdaję sobie sprawę z problemów ze zgodnością.
Pouya
9
moreprzed stworzeniem less. lesszostał stworzony specjalnie w celu usunięcia niedociągnięć more. morenadal istnieje z powodów kompatybilności wstecznej. diri lssą w większości przypadków tymi samymi plikami wykonywalnymi - różnią się tylko garścią bajtów. Nowe narzędzie przeznaczone specjalnie do tworzenia plików zrobi mniej niż istniejących narzędzi i jako taki byłby to regres, a nie poprawa jak w przypadku lessvs more.
lanzz
1
Ponadto musimy przyjrzeć się dziedzictwu, Unix został stworzony, gdy każdy bajt został policzony. Po co tworzyć narzędzie do zadania, które można wykonać za pomocą już istniejącego narzędzia?
Thomas

Odpowiedzi:

38

Powiedziałbym, ponieważ prawie nigdy nie jest konieczne tworzenie pustego pliku, którego zawartość nie wypełni się natychmiast w wierszu poleceń lub w skryptach powłoki.

Najpierw tworzenie pliku, a następnie przekierowanie we / wy do zapisu do pliku nie ma absolutnie żadnej korzyści, jeśli można to zrobić w jednym kroku.

W tych przypadkach, w których naprawdę chcesz utworzyć pusty plik i zostawić go, twierdzę, że > "${file}"nie może być krótszy i bardziej elegancki.

TL; DR : Nie istnieje, ponieważ tworzenie pustych plików najczęściej jest bezużyteczne, aw niektórych przypadkach istnieje już mnóstwo dostępnych opcji, aby osiągnąć ten cel.

Na marginesie: użycie touchdziała tylko wtedy, gdy plik nie istnieje, natomiast opcje wykorzystujące przekierowanie zawsze obcinają plik, nawet jeśli istnieje (więc technicznie rozwiązania te nie są identyczne). > foojest preferowaną metodą, ponieważ oszczędza a forki echo -nnależy jej unikać, ponieważ jest wysoce nieprzenośna.

Adrian Frühwirth
źródło
1
Znalazłem twój punkt widzenia na temat tworzenia pliku, a następnie używania narzędzi I / O, bardzo solidne. Dziękuję Ci.
Pouya
1
@FaheemMitha Tak ( >>). Miałem na myśli przykłady podane przez OP za pomocą >. Dołączanie byłoby zupełnie bezużyteczne, jeśli chodzi o tworzenie plików (lub NOOP, jeśli istnieją).
Adrian Frühwirth
1
Nie zapominaj, że noclobbernie trzeba tego ustawiać, aby >zastąpić istniejący plik.
Ouki,
1
@Ouki AFAIK, ustawienie, które nie jest zachowaniem domyślnym i można zapomnieć, że jest ustawione na jednym systemie, a nie drugim, potencjalnie prowadząc do problemów w taki sam sposób, jak tworzenie alias rm='rm -i'zamiast alias rmi='rm -i'jest złym pomysłem.
Agi Hammerthief,
1
@ mikeserv, > .filew samym wierszu poleceń, zrobi to doskonale bez :.
Charles Duffy,
16

Odpowiedź Adriana Frühwirtha jest słuszna. Chciałem tylko dodać, że nie jest właściwie komenda specjalnie napisany do tworzenia plików: 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.

To prawda, mktempże zadaniem nie jest tworzenie pliku o określonej nazwie, lecz po prostu tworzenie pliku . Jednak, jak już powiedziano, istnieje wiele bardziej wydajnych i eleganckich sposobów tworzenia plików o danej nazwie, dlatego podanie polecenia byłoby bezcelowe.

To powiedziawszy, masz również truncatei fallocatektórych celem jest tworzenie plików. Po prostu mają bardziej wyrafinowane podejście. Nigdy nie będzie prostego programu, który robi to, co > filerobi, ponieważ nie ma sposobu, aby byłby lepszy niż > file.

terdon
źródło
11

Większość podstawowych narzędzi powłoki nie została zaprojektowana w żadnym konkretnym celu. Większość podstawowych narzędzi powłoki zaprojektowano wyłącznie do interakcji z innymi, aby osiągnąć cel. A może należy powiedzieć, że większość narzędzi robi tylko jedną bardzo podstawową rzecz, niezależnie od tego, jak można je połączyć, aby osiągnąć cel.

: >./file

To tworzy pusty plik. Lub obcina istniejący plik, jak chcesz. Możesz:

set -o noclobber

aby uniknąć jakiejkolwiek możliwości tego drugiego przypadku, chyba że:

: >|./file

Możesz uzyskać podobne zachowanie do touch:

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

Tyle że :nie zaktualizuje modtime pliku, ponieważ nie jest modyfikowany.

PRÓBNY

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

WYDAJNOŚĆ

-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

NIE DOTYKAJ

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

WYDAJNOŚĆ

-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
źródło
Domyślnie echo dodaje się \nna końcu linii. Spróbuj echo -n >echo-n.file(rozmiar = 0) i echo -e >echo-e.file(rozmiar = 1)
Thomas
@Thomas 'Ciąg, który należy zapisać na standardowym wyjściu. Jeśli pierwszym operandem jest -n lub jeśli którykolwiek z operandów zawiera znak ukośnika odwrotnego ('\'), wyniki są zdefiniowane w implementacji. W systemach zgodnych z XSI, jeśli pierwszym operandem jest -n, należy go traktować jako ciąg, a nie opcję. Następujące sekwencje znaków będą rozpoznawane w systemach zgodnych z XSI w ramach jednego z argumentów ... ' pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
mikeserv
W porządku, dziękuję za link, a mój komentarz i tak nie ma sensu
Thomas
2
Tak, naprawdę i przepraszam, miałem na myśli to, że mój komentarz i tak nie miał sensu twojej odpowiedzi, przepraszam za to.
Thomas
1
Ilustracją tendencji Uniksa do uogólnienia jest fakt, że wywoływane jest polecenie wyświetlania zawartości pliku cat. Dlaczego masz polecenie do wyświetlenia jednego pliku, skoro możesz wykonać jedno polecenie, aby połączyć wiele plików w standardowe wyjście?
200_success 11.04.14
1

Narzędzie installjest rzeczywiście przeznaczone do tworzenia plików! Możesz przekazać zawartość pliku przez /dev/stdin(w większości przypadków jednak w większości wersji Linuksa, wymaga /procto zamontowania) lub podać inny plik źródłowy. Możesz ustawić własność i uprawnienia.

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

jako głupi przykład.

Otheus
źródło