Okungalindelekile okungafakwanga ukufaka ikhodi kwe- / proc / / cmdline

С GNU sed:

sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q}; $q1'

Как это работает

  • 132 {/ ^ # termcapinfo [[: space:] ] * xterm Z0 = / q}

    В строке 132 проверьте наличие регулярного выражения ^ # termcapinfo [[: space:]] * xterm Z0 = . Если обнаружено, выйти, q , с кодом выхода по умолчанию 0. Остальная часть файла пропускается.

  • $ q1

    Если мы дойдем до последней строки, $ , тогда выйдите с кодом выхода 1: q1 .

Эффективность

Поскольку нет необходимости читать после 132-й строки файла, эта версия завершается, как только мы дойдем до 132-й строки или конца файла, в зависимости от того, что произойдет раньше:

sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q; q1}; $q1'

Обработка пустых файлов

Вышеупомянутая версия вернет истину для пустых файлов. Это связано с тем, что, если файл пуст, никакие команды не выполняются и sed завершает работу с кодом выхода по умолчанию 0. Чтобы этого избежать:

! sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q1; q}'

Здесь команда sed завершается с кодом 0, если не найдена нужная строка, в которой в случае выхода с кодом 1 Предыдущий ! указывает оболочке инвертировать этот код, чтобы вернуться к желаемому коду. ! Модификатор поддерживается всеми оболочками POSIX. Эта версия будет работать даже с пустыми файлами. (Совет шляпы: G-Man)

2
22.03.2018, 06:57
1 ответ

at least one uses spaces for delimiters

Неверно.

Если вы посмотрите в конец псевдофайла -в FreeBSD/TrueOS, где вы можете столкнуться с точно таким же поведением с Chromium, вы найдете . Это равно и #x2400; -прекращено. Это все один единственный аргумент .

Chromium перезаписывает свои аргументы после fork(), чтобы дать вам что-то интересное для просмотра в выводе ps. Он использует библиотечную функцию setproctitle(). Это часть библиотек BSD C. Он не является частью библиотеки GNU C. На платформах GNU C Chromium использует и setproctitle()собственный , который напрямую перезаписывает данные argv.

setproctitle()на самом деле не является подходящим инструментом для этой работы, потому что он не позволяет устанавливать более одной строки аргументов. Он устанавливает отформатированное «заголовок» в качестве 0-го аргумента и устанавливает количество аргументов равным 1. Все сортируется через библиотечную функцию как один единственный аргумент.

Это не единственная проблема с setproctitle(). Версия библиотеки C для FreeBSD/OpenBSD/NetBSD также имеет произвольное ограничение в 2 КБ, унаследованное непосредственно от старой программы BSD sendmail(, из которой библиотечная функция была первоначально удалена в случае FreeBSD ), что слишком мало. для чего Chromium часто устанавливает командные строки. И собственная версия библиотеки Chromium, и версия библиотеки FreeBSD/OpenBSD/NetBSD C имеют дополнительную функциональность, поскольку строка формата является нулевым указателем, который Chromium не использует (, но, по иронии судьбы, должен иметь дело с собственной реализацией setproctitle(). тем не менее ).

Можно сделать намного лучше, используя меньше кода.Базовый системный вызов в FreeBSD/TrueOS, который библиотечная функция вызывает для выполнения работы после создания данных аргумента, — это функция sysctl(), принимающая CTL_KERN, KERN_PROC, KERN_PROC_ARGSи идентификатор процесса в качестве адреса. Этот может принимать несколько & #x2400; -завершенные строки. Я написал довольно простую функцию setprocargv()для своих наборов инструментов, которая использует это.

extern
void
setprocargv (
    size_t argc,
    const char * argv[]
) {
#if defined(__FreeBSD__) || defined(__DragonFly__)
    std::string s;
    for (size_t c(0); c < argc; ++c) {
        if (!argv[c]) break;
        s += argv[c];
        s += '\0';
    }
    const int oid[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() };
    sysctl(oid, sizeof oid/sizeof *oid, 0, 0, s.data(), s.length());
#elif defined(__OpenBSD__) …

(OpenBSD/NetBSD работает по-старому, как FreeBSD/TrueOS, со структурой ps_stringsв памяти приложения, но по-прежнему sysctl()является базовым системным вызовом, используемым для поиска местоположения этой структуры..)

% /package/admin/nosh/command/exec foreground pause \; true &
[1] 30318
% hexdump -C /proc/30318/cmdline
00000000  66 6f 72 65 67 72 6f 75  6e 64 00 70 61 75 73 65  |foreground.pause|
00000010  00 3b 00 74 72 75 65 00                           |.;.true.|
00000018
% hexdump -C /proc/30319/cmdline
00000000  70 61 75 73 65 00                                 |pause.|
00000006
%

Поскольку setproctitle()не подходит для этой работы, Chromium берет новые argvчлены и создает единый long & #x2420; -строка из них с разделителями, которая должна быть передана как один аргумент в setproctitle().

  for (size_t i = 1; i < command_line->argv().size(); ++i) {
    if (!title.empty())
      title += " ";
    title += command_line->argv()[i];
  }
  // Disable prepending argv[0] with '-' if we prepended it ourselves above.
  setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());

Как видите, сам Chromium уже имеет новый вектор аргументов в виде последовательности & #x2400; -завершенные строки. Он передает его через промежуточный библиотечный уровень, который требует, чтобы все они были сгруппированы в одну строку, где фактический уровень системного вызова, тем не менее, оперирует вектором аргументов & #x2400; -завершенные строки.

Отсюда и поведение, которое вы наблюдаете, когда Chromium представляет свои измененные векторы аргументов системе как один единственный аргумент .

Возможно, вы могли бы убедить авторов Chromium принять что-то вроде setprocargv(). & #9786;

Дополнительная литература

  • Питер Вемм (1995 -12 -16 ).setproctitle. Руководство по функциям библиотеки FreeBSD . FreeBSD.
9
27.01.2020, 21:52

Теги

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