find . -type d -exec chmod 755 {} + -or -type f -exec chmod 644 {} +
find ... -exec ... +
похожfind ... -exec ... \;
за исключением того, что команда выполняется только однажды на большой набор соответствия файлам.Давным-давно,
find OPTIONS... -exec COMMAND... \;
должен был действовать на один файл за один раз. Такxargs
был изобретен к действиям группы для эффективности. Ноxargs
представленный его собственная доля проблемы: это ожидает вход, который заключается в кавычки способом этоfind
не может произвести. Такfind OPTIONS... | xargs COMMAND...
бесполезно, если Вы не знаете, что Ваши имена файлов не содержат ни одного из'"\
или пробел.Затем GNU изобретен
find OPTIONS... -print0 | xargs -0 COMMAND...
, который позволяет любому символу появляться в имени файла. Но требовалось много времени, чтобы кто-либо еще принял его, и тем временем Sun (я думаю), изобретенныйfind OPTIONS... -exec COMMAND... +
, который делает то же задание группировки какxargs
, без добавленных сложностей (более длительная командная строка, ограничьте одной наfind
команда). Теперьfind ... -exec ... +
является стандартным (это находится в Единственном Unix v3), и более широко доступный, чемxargs -0
. Если Вы не должны поддерживать совместимость со старой системой Linux, просто забудьте оxargs
.
Смотря на источник ядра Linux, я вижу, что, если файл/init существует, ядро будет всегда пытаться выполнить его при условии, что он делает начальную загрузку электронного диска. Проверьте свою систему, чтобы видеть, существует ли/init, если это делает, затем это - вероятно, Ваша проблема.
На
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
Я нашел:
При отладке нормальной корневой файловой системы хорошо смочь загрузиться с "init =/bin/sh". initramfs эквивалент "rdinit =/bin/sh", и это столь же полезно.
Так, вероятно, пробуют ridinit =/bin/sh
Вы можете настроить ядро Linux и перекомпилировать его. Для ядра 4.9 отредактируйте функцию "kernel_init" в файле init/main.c и попробуйте сначала выполнить следующую строку:
try_to_run_init_process("/bin/sh")
Кроме того, это может быть вызвано параметрами ядра, переданными BootLoader.
второстепенные махинации
Если вы используете initrd или initramfs, имейте в виду следующее:
rdinit=
используется вместоinit=
если rdinit=
не задано, пробные пути по умолчанию: :/sbin/init
, /etc/init
, /bin/init
и /bin/sh
, но не/init
Если initrd не используется, /init
является первым пробным путем, за которым следуют остальные.
v4.15 RTFS :все содержится внутри файла https://github.com/torvalds/linux/blob/v4.15/init/main.c.
Сначала мы узнаем, что:
execute_comand
это то, что передается:init=
ramdisk_execute_command
это то, что передается:rdinit=
как видно из:
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
/*
* In case LILO is going to boot us with default command line,
* it prepends "auto" before the whole cmdline which makes
* the shell think it should execute a script with such name.
* So we ignore all arguments entered _before_ init=... [MJ]
*/
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
static int __init rdinit_setup(char *str)
{
unsigned int i;
ramdisk_execute_command = str;
/* See "auto" comment in init_setup */
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("rdinit=", rdinit_setup);
, где __setup
— волшебный способ обработки параметров командной строки.
start_kernel
, ядро "точка входа", вызывает rest_init
, который "вызывает" kernel_init
поток:
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
Тогда kernel_init
делает:
static int __ref kernel_init(void *unused)
{
int ret;
kernel_init_freeable();
[...]
if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\n",
ramdisk_execute_command, ret);
}
[...]
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
panic("Requested init %s failed (error %d).",
execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/admin-guide/init.rst for guidance.");
}
и kernel_init_freeable
делает:
static noinline void __init kernel_init_freeable(void)
{
[...]
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
}
TODO :понять sys_access
.
Также обратите внимание, что существуют дополнительные различия между ram-инициалами и не -ram-инициалами, например. работа с консолью:Разница в выполнении init со встроенными и внешними initramfs?
execute_command
во-первых, который прибывает из командной строки ядраinit=
параметр. Если это не может выполнить его, это печатает предупреждение и попытки работатьinit
в различных местоположениях. Это находится вinit/main.c
в функцииinit_post()
. Я просмотрел ядро printk сообщения и нашел предупреждение в выводе моего ядра, поэтому теперь я должен выяснить, почему это не может запустить/bin/sh или что-либо еще, что я пытаюсь запустить. – Shawn J. Goff 31.01.2012, 06:00rdinit
при начальной загрузке от электронного диска, по-видимому: unix.stackexchange.com/a/430614/32558 – Ciro Santilli 新疆改造中心法轮功六四事件 16.03.2018, 14:37