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 КБ, унаследованное непосредственно от старой программы BSDsendmail
(, из которой библиотечная функция была первоначально удалена в случае 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.
Если параметры, начинающиеся с -
, никогда не принимают аргументы, достаточно просто использовать массивopts
:
for a; do
shift
case $a in
-*) opts+=("$a");;
*) set -- "$@" "$a";;
esac
done
(измените opts+=("$a")
на opts="$opts$a "
, если вы хотите, чтобы opts
было строкой, что заставит фрагмент работать с любой стандартной оболочкой ).
В bash, ksh, zsh одно расширение очистит все аргументы, начинающиеся с-
:
echo "${@##-*}"
Обратите внимание, что это не удаляет аргументы, а просто делает их нулевыми.
Однако получить список аргументов, который не начинается с -
, имея при этом возможность работать с пробелами и символами новой строки, становится гораздо сложнее.
Простая петля предпочтительнее:
unset args opts;
for a; do
if [[ $a == [-]* ]]; then
opts+=("$a");
else
args+=("$a");
fi;
done;
printf '<%s> ' "${args[@]}"; echo;
printf '<%s> ' "${opts[@]}"; echo;