sed -E 's/([^\t]+)\t([^\t]+)/\1-\2/g'
sed -E 's/foo/bar/g'
:запустить sed
с -E
расширенным регулярным выражением, заменив foo
на bar
, несколько раз в строке /g
. ([^\t]+)\t([^\t]+)
:соответствует не -символу табуляции [^\t]
, состоящему из одного или нескольких символов +
, и фиксирует его в группе ([^\t]+)
. Затем следует табуляция, затем символы табуляции, отличные от -, снова в другой группе захвата. \1-\2
:замените это первой группой захвата, -
, затем второй группой захвата. По сути, замените вкладку на -
. sed
является "жадным", т.е. пытается захватить как можно больше символов. Следовательно, две группы захвата будут стараться быть как можно дольше. например. он захватит все a antartica
(, заменив его наa-antartica
). При следующем запуске поиска он уже прошел antartica
, и снова начинает поиск на вкладке после этого слова. Следовательно, следующим совпадением будет 1 1
, которое будет заменено на 1-1
. Затем этот шаблон будет повторяться для каждой пары столбцов. Жадный +
важен. Если вы опустите его, шаблон просто изменит каждую вкладку.
Вход в подсистему кажется действительно -плохо документированной функцией. Чтобы разобраться, может понадобиться немного поиска по исходному коду. Давайте посмотрим на Debian 11login.c
.
Часть, связанная с входом в подсистему , начинается с строки 1151:
if (pwd->pw_shell[0] == '*') { /* subsystem root */
pwd->pw_shell++; /* skip the '*' */
subsystem (pwd); /* figure out what to execute */
subroot = true; /* say I was here again */
endpwent (); /* close all of the file which were */
endgrent (); /* open in the original rooted file */
endspent (); /* system. they will be re-opened */
#ifdef SHADOWGRP
endsgent (); /* in the new rooted file system */
#endif
goto top; /* go do all this all over again */
}
Если звездочка обнаружена в начале поля shell
, звездочка удаляется (, поэтому вы никогда не увидите *-bash
в списке процессов ), а функция subsystem()
вызывается для входа этого пользователя. Здесь pwd
— это структура, содержащая информацию, эквивалентную пользовательской строке в /etc/passwd
.
Когда инициируется вход в подсистему, вся обработка паролей и групповых записей также прекращается. Из комментариев здесь вы должны догадаться, что вход в подсистему как-то связан с chroot()
.
goto top;
возвращается к строке #717 , эффективно перезапуская процесс аутентификации и установки сеанса -, теперь используя файлы конфигурации внутри chroot.
Функция subsystem()
определена в sub.c-фактически, это единственная функция в этом файле:
/*
* subsystem - change to subsystem root
*
* A subsystem login is indicated by the presence of a "*" as
* the first character of the login shell. The given home
* directory will be used as the root of a new filesystem which
* the user is actually logged into.
*/
void subsystem (const struct passwd *pw)
{
/*
* The new root directory must begin with a "/" character.
*/
if (pw->pw_dir[0] != '/') {
printf (_("Invalid root directory '%s'\n"), pw->pw_dir);
SYSLOG ((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
closelog ();
exit (EXIT_FAILURE);
}
/*
* The directory must be accessible and the current process
* must be able to change into it.
*/
if ( (chdir (pw->pw_dir) != 0)
|| (chroot (pw->pw_dir) != 0)) {
(void) printf (_("Can't change root directory to '%s'\n"),
pw->pw_dir);
SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
closelog ();
exit (EXIT_FAILURE);
}
}
И вот что у нас есть :a логин подсистемы — это логин, chroot()
привязанный к домашнему каталогу пользователя, как указано в /etc/passwd
. Например, если у вас есть пользователь subsys
, определенный таким образом в/etc/passwd
:
subsys:x:999:999:Subsystem login example:/home/subsys:*chrooted*
Когда этот пользователь входит в систему, используя login
(, т. е. с текстовой консоли или через последовательный порт ), пользователь будет chroot, так что он увидит свой домашний каталог /home/subsys
как /
. Затем процесс аутентификации повторяется с использованием файлов конфигурации в /home/subsys/etc
.
Обратите внимание, что в случае входа в подсистему содержимое поля оболочки фактического /etc/passwd
после первого символа *
фактически игнорируется. Как только chroot будет выполнен, процесс login
будет читать /home/subsys/etc/passwd
для реальной оболочки, которая будет использоваться для этого пользователя.
Как всегда, при настройке chroot вы должны убедиться, что все необходимые файлы библиотек, файлы конфигурации и устройства существуют в chroot, так как программы, запущенные в chroot, не смогут получить доступ к чему-либо за пределами chroot. Таким образом, в этом примере вам нужно будет создать хотя бы минимальный /home/subsys/lib
, /home/subsys/etc
(, включая как минимум /home/subsys/etc/passwd
, /home/subsys/etc/shadow
, /home/subsys/etc/pam.d/login
и, возможно, другие файлы )и обычно не менее /home/subsys/dev/null
.
В зависимости от того, для чего вы используете вход в подсистему, вам могут понадобиться и другие устройства :для оболочек, вам, вероятно, понадобится /home/subsys/dev/ptmx
и файловая система devpts
в /home/subsys/dev/pts
. Вы можете настроить их так:
# these steps need only be done once:
mkdir -p /home/subsys/dev/pts
mknod /home/subsys/dev/null c 1 3
mknod /home/subsys/dev/ptmx c 5 2
chmod 0666 /home/subsys/dev/null /home/subsys/dev/ptmx
# this needs to be re-done after every boot:
mount -t devpts none /home/subsys/dev/pts
Таким образом, ваш /home/subsys/etc/passwd
должен иметь запись для chroot-пользователя subsys
, что-то вроде этого:
subsys:x:999:999:A subsystem user:/subsyshome:/bin/bash
Это будет означать, что фактический домашний каталог пользователя будет находиться в /home/subsys/subsyshome
, и вам также потребуется указать /home/subsys/bin/bash
и все необходимые для него библиотеки.