Bash: Почему * не возвращает пустую строку в случае отсутствия совпадений [дубликат]

Клиент-серверные программы графического интерфейса пользователя

Как и несколько других программ графического интерфейса пользователя в настоящее время, с 2008 года lxterminal пытается отображать все окна эмулятора терминала из одного процесса, по одному на каждый дисплей X для каждого пользователя. Для этого он пытается подключиться к существующему сокету по имени, которое вы видите, которое включает отображаемое имя и ваше имя пользователя.

  • Если соединение установлено успешно, оно просто выгружает текущий каталог и вектор аргументов в сокет и завершает работу. Он не использует передачу файлового дескриптора для прямой передачи открытого файлового дескриптора в текущий каталог, а передает его по имени.
  • Если соединение не удается, он пытается сам стать слушающим сервером на этом сокете. Он считывает сообщения, содержащие текущий каталог и вектор аргументов, и открывает новое окно эмуляции терминала GUI для каждого чтения, как если бы это был его собственный текущий каталог и вектор аргументов.

Видимый эффект этого заключается в том, что первая lxterminal программа, которую вы вызываете (и оставляете запущенной), работает синхронно, а вторая и последующие - нет. Чтобы увидеть это, начните с no lxterminal запущенных экземпляров, запустите другой эмулятор терминала и вызовите

lxterminal & sleep 1 ; lxterminal

из оболочки. Оболочка вернется к приглашению через 1 секунду и покажет только одно оставшееся lxterminal задание.

rxvt имеет аналогичную возможность, но необходимо явно вызвать ] urxvtd и явно запустить клиент urxvtc .Запуск простого urxvt не выполняет никаких действий клиент-сервер.

Терминал GNOME только , напротив, работает таким же образом. Он всегда передает вектор аргументов серверному процессу и затем завершает работу. Более того, существует только один серверный процесс для каждого пользователя, обрабатывающий все дисплеи (и ошибки в способе инициализации этого механизма для загрузки).

небезопасность

Создание файлов и сокетов в / tmp с предсказуемыми именами является хорошо известной проблемой безопасности, и lxterminal разделяет ее. Пользователи могут заранее создать сокеты в предсказуемых местах, с которыми lxterminal , запущенные другими пользователями на той же машине, будут пытаться общаться.

rxvt, напротив, использует подкаталог домашнего каталога каждого пользователя без возможности записи для группы и без возможности записи для других. Другой возможностью для решения этой проблемы с lxterminal , который в равной степени не позволит другим пользователям доступ для замены своих сокетов на свои, будет наличие сокетов в / run / user / имя пользователя / lxterminal .

(Терминал GNOME использует шину рабочего стола уровня пользователя для связи между клиентами и своим сервером. В настоящее время сокет AF_LOCAL для этого находится в / run / user / имя пользователя / , где он не может быть вытеснен другими непривилегированными пользователями.)

ошибки

Одна из проблем, с которыми сталкивается GNOME Terminal, заключается в том, что он занимает много открытых файловых дескрипторов в процессе одного сервера для каждого экземпляра эмуляции терминала.Раньше было 16; и теперь «всего лишь» 8.

lxterminal использует 2, один из которых - утечка дескриптора открытого файла для сокет-соединения клиентского процесса. Откройте и закройте достаточно эмуляции терминала, и в конечном итоге на lxterminal закончатся доступные файловые дескрипторы. Следующее, начиная с отсутствия запущенных экземпляров lxterminal , использовало все доступные файловые дескрипторы сервера чуть более чем за минуту на одной из моих машин:

(ulimit -H -n 1024 ; lxterminal) &
seq 0 1024 | while read -r i ; do lxterminal -e /usr/bin/true ; done

Дальнейшее чтение

1
13.04.2017, 15:37
2 ответа

На самом деле * расширяется bash (какой бы ни была ваша оболочка), а затем передается echo. Команда echo ничего не делает, только печатает его на стандартный вывод. Прочитайте этот документ - Расширение имени файла. В нем говорится -

Bash сканирует каждое слово на наличие символов "*", "?" и "[". Если один из этих символов появляется, то слово рассматривается как ПАТТЕРН и заменяется отсортированным по алфавиту списком имен файлов, соответствующих шаблону. Если подходящих имен файлов не найдено, а опция оболочки nullglob отключена, то слово оставляется без изменений. Если опция nullglob установлена, и совпадений не найдено, слово удаляется.

Таким образом, когда bash не может найти ни одного совпадения, он оставляет '*' без изменений, и echo печатает это.

Причина Причина, по которой bash не возвращает пустой оператор по умолчанию, в том, что могут быть случаи, когда пользователь не хочет использовать '*' в качестве подстановочного знака, и поэтому ему не нужно расширение '*'. Следовательно, в этом случае расширение '*' до пустой строки будет ошибочным. Однако это поведение по умолчанию может быть отменено опцией nullglob.

1
27.01.2020, 23:16

Шаблоны, не соответствующие ни одному файлу, считаются ошибкой. Вы можете видеть это в самых первых версиях unix.

glob выводит ошибку, а переданная команда никогда не запускается.

Сообщение об ошибке «Нет совпадений» .

В вашей современной оболочке, производной от Bourne (версия Unix 7) , ls -l * .c выдает ошибку «* .c: Нет такого файла или каталога». Я бы сказал, что это сообщение легче понять; также это указывает на шаблон, который потерпел неудачу.

Обратите внимание, что если *. C было расширено до пустого, ls -l * .c вместо этого отобразит все файлы в каталоге и не выведет ошибки.

bash имеет параметр failglob для поведения, близкого к исходному.

5
27.01.2020, 23:16

Теги

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