W przypadku polecenia użycie -
argumentu zamiast nazwy pliku oznacza STDIN lub STDOUT.
Ale w tym przykładzie tworzy plik o nazwie
-
:echo hello > -
Jak mogę zrobić
-
w tym przykładzie oznaczać STDOUT?I odwrotnie, jak mogę utworzyć
-
plik nazwany-
w przykładach takich jak:cat -
2>&-
konstrukcje, co oznacza „ścisły deskryptor 2”.Odpowiedzi:
Użycie
-
jako nazwy pliku w celu oznaczenia stdin / stdout to konwencja używana przez wiele programów. To nie jest specjalna właściwość nazwy pliku. Jądro nie rozpoznaje-
jako specjalnego, więc wszelkie wywołania systemowe określane-
jako nazwa pliku będą używane-
dosłownie jako nazwa pliku.Z przekierowaniem bash
-
nie jest rozpoznawany jako specjalna nazwa pliku, więc bash użyje go jako dosłownej nazwy pliku.Kiedy
cat
widzi ciąg-
jako nazwę pliku, traktuje go jako synonim standardowego wejścia. Aby obejść ten problem, musisz zmienić ciąg, którycat
widzi, tak aby nadal odwoływał się do pliku o nazwie-
. Zwykle jest to poprzedzone nazwą pliku ścieżką -./-
lub/home/Tim/-
. Technikę tę stosuje się również w celu obejścia podobnych problemów, w których opcje wiersza poleceń kolidują z nazwami plików, więc plik określany jako./-e
nie pojawia się na przykład jako-e
opcja wiersza polecenia programu.źródło
/dev/stdin
i/dev/stdout
są one powszechnie dostępne i mogą być używane zamiast-
konwencji.cat
przypadku użycie przekierowania zamiast wyświetlania argumentu może pomóccat <-
:; trudno byłoby jednak mieszać i łączyć to z łączeniem więcej niż jednego pliku na raz.jmtd
pytanie? :)Zamiast tego
echo hello > -
możesz użyćecho hello > /dev/stdout
.Chociaż „-” to konwencja, która musi zostać zaimplementowana przez każdy program, który chce go obsługiwać
/dev/stdin
,/dev/stdout
i/dev/stderr
jest obsługiwana przez system operacyjny (przynajmniej Solaris, Linux i BSD) niezależnie od aplikacji, a następnie będzie działała tak, jak Ty zamierzać.źródło
Jak wspomniano camh ,
-
to tylko konwencja nazewnictwa używana przez niektóre programy. Jeśli chcesz odwoływać się do tych strumieni za pomocą deskryptora pliku, który rozpozna powłoka, jiliagre miał rację , używając nazwy/dev/stdin
lub/dev/stdout
zamiast niej. Te nazwy plików powinny działać w każdym miejscu, w którym działałaby normalna nazwa pliku.Biorąc to pod uwagę, twój pierwszy przykład jest trochę głupi. Wszelkie dane wyjściowe, które operator przekierowania przechwyciłby, aby zapisać do pliku, są już na standardowym wyjściu, więc przekierowanie go i zapisanie go tam, skąd pochodzi, jest bezużyteczne. Zachowanie, którego tam używasz, to potok, a nie przekierowanie:
W drugim przykładzie wystarczy podać, że można wskazać, że chcesz mieć plik literalny o tej nazwie, a nie jego wewnętrzny alias. Możesz to zrobić najłatwiej, określając ścieżkę do pliku w następujący sposób:
źródło
Jeśli chodzi o 1, program musi go obsługiwać. Nie możesz po prostu arbitralnie z niego korzystać. Jeśli chodzi o 2, przekieruj dane wejściowe z (np
cat < -
.).źródło
Podejście „-” ma wiele problemów. Przede wszystkim wymaga interpretacji znaku „-”, a wiele programów nie dokonuje takiej interpretacji. Ponadto istnieją programy, które interpretują łącznik jako ogranicznik oznaczający koniec opcji wiersza poleceń. Programy są napisane do pracy z argumentami nazw plików, podejście „-” to hack, ładne, ale słabe.
Najlepszym sposobem jest:
/dev/stdout
to symbolik link do/dev/fd/1
źródło