Для команды, если использовать -
в качестве аргумента вместо имени файла, будет означать STDIN или STDOUT.
Но в этом примере он создает файл с именем
-
:echo hello > -
Как я могу сделать
-
в этом примере означает STDOUT?И наоборот, как я могу
-
обозначить файл, указанный-
в примерах, таких как:cat -
2>&-
конструкция, что означает «закрыть дескриптор 2».Ответы:
Использование
-
в качестве имени файла значения stdin / stdout - это соглашение, которое используют многие программы. Это не специальное свойство имени файла. Ядро не распознает-
как особые, поэтому любые системные вызовы со ссылкой на-
имя файла будут использовать-
буквально как имя файла.С перенаправлением bash
-
не распознается как специальное имя файла, поэтому bash будет использовать его как буквальное имя файла.Когда
cat
видит строку-
как имя файла, он воспринимает ее как синоним stdin. Чтобы обойти это, вам нужно изменить строку, котораяcat
видит таким образом, что она по-прежнему ссылается на файл с именем-
. Обычный способ сделать это состоит в том, чтобы префикс имени файла с путем -./-
, или/home/Tim/-
. Этот метод также используется для обхода подобных проблем, когда параметры командной строки конфликтуют с именами файлов, поэтому файл, на который ссылаются./-e
, не отображается, например, как параметр-e
командной строки для программы.источник
/dev/stdin
и/dev/stdout
повсеместно доступны и могут быть использованы вместо-
конвенции.cat
случае, используя перенаправление вместо перечисления аргумент может помочь:cat <-
; однако было бы трудно смешивать и сопоставлять это с конкатенацией более одного файла за раз.jmtd
вопрос? :)Вместо
echo hello > -
, вы можете использоватьecho hello > /dev/stdout
.Хотя '-' - это соглашение, которое должно быть реализовано каждой программой, желающей его поддерживать
/dev/stdin
,/dev/stdout
и/dev/stderr
, когда поддерживается ОС (по крайней мере, Solaris, Linux и BSD), не зависит от приложения и будет работать как вы. намерены.источник
Как уже упоминалось в camh ,
-
это просто соглашение об именах, используемое некоторыми программами. Если вы хотите сослаться на эти потоки с помощью файлового дескриптора, который распознает оболочка, jiliagre был прав, когда вы использовали имя/dev/stdin
или/dev/stdout
вместо него. Эти имена файлов должны работать в любом месте, где будет работать нормальное имя файла.Тем не менее, ваш первый пример немного глупый. Любой вывод, который будет перехвачен оператором перенаправления для записи в файл, уже включен в стандартный вывод, поэтому перенаправление и обратная запись туда, откуда он пришел, бесполезно. Поведение, которое вы используете, это канал, а не редирект:
Во втором примере вам просто нужно указать, что вам нужен литеральный файл с таким именем, а не его внутренний псевдоним. Вы можете сделать это проще всего, указав путь к файлу следующим образом:
источник
Что касается 1, программа должна поддерживать его. Вы не можете просто использовать это произвольно. Что касается 2, перенаправить ввод с (например,
cat < -
).источник
Подход «-» имеет много проблем. Прежде всего, это требует интерпретации символа «-», и многие программы не выполняют такую интерпретацию. Более того, есть некоторые программы, которые интерпретируют дефис как разделитель, обозначающий конец параметров командной строки. Программы написаны для работы с аргументами имени файла, подход «-» - хак, хороший, но слабый.
Лучший способ это:
/dev/stdout
является символической ссылкой/dev/fd/1
источник