Есть ли что-то особенное в `<. `и это `эхо `поведение?

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

set -- *
printf '%s %s\n' "$@"  > output

или только определенные файлы:

set -- *_R?.fastq

Порядок зависит от раскрытия подстановочного знака, который вы использовали. Если вы хотите больше контролировать последовательность, вы можете как-то вручную разделить глоб, например:

set -- Paleo*.fastq Vegan*.fastq Omnivore*.fastq FastFood*.fastq
-1
11.10.2020, 07:01
2 ответа

Если да

strace mail <dest> <.

вы можете увидеть, что произошло (хотя вам придется присмотреться ). В системе Linux (, как отмечается в комментарии, другие системы Unix могут вести себя иначе, если чтение каталога завершилось успешно ), имеется около 200 строк вывода, большая часть которых инициализируется, но есть три очень важных строки, в моем случае строки 153, 165 и 191:

...
read(0, 0x556829edb730, 8192)           = -1 EISDIR (Is a directory)
...
write(1, "No message, no subject; hope tha"..., 39No message, no subject; hope that's ok) = 39
...
write(4, "Date: Sat, 10 Oct 2020 23:19:22 "..., 212) = 212
...
exit_group(0)                           = ?
+++ exited with 0 +++

IOW, он попытался прочитать файловый дескриптор 0 (из своего стандартного ввода )и получил ошибку EISDIR:, потому что оболочка перенаправила ., т.е. текущий каталог в качестве стандартного ввода, а readне является разрешено читать каталог. Но почтовая программа проигнорировала эту ошибку, написала сообщение в своем файловом дескрипторе 1 )stdout (о том, что не было ни сообщения, ни темы, переданной ей, и что она надеялась, что все в порядке, а затем приступила к составлению почтового сообщения. и записать его в файловый дескриптор 4, который предположительно каким-то образом подключен для отправки сообщения (сообщение состоит из 212 символов ). Также обратите внимание, что программа завершается со статусом 0 (нормальный выход ).

Если вы попробуете то же самое с catили tr, как предлагает @thanasisp в своем ответе, вы увидите немного другой результат. Эти программы по-прежнему пытаются читать из файлового дескриптора 0 и получают ошибку EISDIR -, но они НЕ игнорируют ошибку; вместо этого они выходят с сообщением об ошибке и не -нулевым статусом:

$ strace cat <.
...
read(0, 0x7fc27daec000, 131072)         = -1 EISDIR (Is a directory)
write(2, "cat: ", 5cat: )                    = 5
write(2, "-", 1-)                        = 1
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Is a directory", 16: Is a directory)        = 16
write(2, "\n", 1
)                       = 1
munmap(0x7fc27daeb000, 139264)          = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

Но нет никакой разницы в том, как обрабатывается <.:в обоих случаях оболочка связывает файл (текущий каталог )с файловым дескриптором 0 (стандартный ввод )исполняемую программу. Но программы по-разному реагируют на ошибку. Это все.

Кстати,ответ @thanasisp является точным -и отвечает на большинство ваших вопросов (, даже если он немного скрывает тонкую разницу между командой mailи, например,. trили cat, на чем я сосредоточусь в этом ответе ).

2
18.03.2021, 22:57

Точка обозначает текущий каталог, вы можете видеть, что в типичных обычных командах, таких как find., cp path/filename.и т. д., это означает «здесь». Также точка является синонимом команды source, вы можете увидеть это, набрав man..

В вашем случае точка используется как текущий каталог, потому что этот синтаксис:

command < path/to/something

— это перенаправление на стандартный ввод команды, как вы можете видеть в руководстве bash , а этот синтаксис:

command < path/to/something argument

то же, что и выше, только с одним дополнительным аргументом, то же самое:

command argument < path/to/something

Итак, в вашем случае echoне жалуется, потому что он вообще не читает свой стандартный ввод, читает только следующую строку и печатает ее.

Это лучше видно с другими командами, например tr, которая читает только стандартный ввод:

tr <. 'a' 'b' # or tr 'a' 'b' <.
tr: read error: Is a directory
tr < file 'a' 'b' # works.
2
18.03.2021, 22:57

Теги

Похожие вопросы