Почему в простой команде bash нет явного клона или вилки и как это делается?

Похожий на старый Norton Commander в Unix - это Midnight Commander. Я использую его много лет, и в некоторых ситуациях он особенно полезен.

Чтобы установить его в Debian, выполните:

apt-get install mc

Чтобы запустить его, вызовите

mc

Помимо знакомого текстового графического интерфейса, в нижней (командной) строке вы также можете выполнять команды оболочки.

Некоторые функции также связаны с командами по умолчанию, и вы можете создавать новые ассоциации.

Midnight Commander также понимает ssh / scp, и одно из двух текстовых окон может быть удаленным.

https://www.midnight-commander.org

7
03.09.2018, 10:01
2 ответа

sh -c 'command line'обычно используются такими вещами, как system("command line"), ssh host 'command line', viи !, cron, и вообще всем, что используется для интерпретации командной строки, так что это довольно важно сделать его максимально эффективным.

Разветвление требует больших затрат процессорного времени, памяти, выделенных файловых дескрипторов... Если процесс оболочки просто ожидает другого процесса перед выходом, это просто пустая трата ресурсов. Кроме того, это затрудняет правильное сообщение о статусе выхода отдельного процесса, который будет выполнять команду (, например, когда процесс будет убит ).

Многие оболочки обычно пытаются свести к минимуму количество ответвлений в качестве оптимизации. Даже не оптимизированные -оболочки, такие как bash, делают это в случаях sh -c cmdили (cmd in subshell). В отличие от ksh или zsh, он не делает этого в bash -c 'cmd > redir'илиbash -c 'cmd1; cmd2'(в подоболочках ). ksh93 — это процесс, который дальше всего избегает форков.

Бывают случаи, когда эту оптимизацию выполнить невозможно, например при выполнении:

sh < file

Где shнельзя пропустить разветвление для последней команды, потому что во время выполнения этой команды к сценарию может быть добавлен дополнительный текст. А для файлов, не доступных для поиска -, он не может обнаружить конец -файла -, поскольку это может означать слишком раннее чтение из файла.

или:

sh -c 'trap "echo Ouch" INT; cmd'

Где оболочке может потребоваться выполнить больше команд после выполнения «последней» команды.

10
27.01.2020, 20:15

Копаясь в исходном коде bash, я смог выяснить, что bash на самом деле будет игнорировать разветвления, если нет каналов или перенаправлений. Из строки 1601 в выполнить _cmd.c:

  /* If this is a simple command, tell execute_disk_command that it
     might be able to get away without forking and simply exec.
     This means things like ( sleep 10 ) will only cause one fork.
     If we're timing the command or inverting its return value, however,
     we cannot do this optimization. */
  if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) &&
      ((tcom->flags & CMD_TIME_PIPELINE) == 0) &&
      ((tcom->flags & CMD_INVERT_RETURN) == 0))
    {
      tcom->flags |= CMD_NO_FORK;
      if (tcom->type == cm_simple)
    tcom->value.Simple->flags |= CMD_NO_FORK;
    }

Позже эти флаги переходят к execute_disk_command()функции, которая устанавливает целочисленную переменную nofork , которая затем проверяется перед попыткой разветвления .Сама фактическая команда будет запускаться execve()оболочкой функциональной оболочкой _execve()из разветвленного или родительского процесса, и в этом случае это фактический родитель.

Причина такой механики хорошо объяснена в ответе Стефана .


Дополнительное примечание, выходящее за рамки этого вопроса :, следует отметить, что, по-видимому, имеет значение, является ли оболочка интерактивной или работает через -c. Перед выполнением команды будет форк. Это видно из запуска straceв интерактивной оболочке(strace -e trace=process -f -o test.trace bash)и проверки выходного файла :

.
19607 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_t
idptr=0x7f2d35e93a10) = 19628
19607 wait4(-1,  <unfinished...>
19628 execve("/bin/true", ["/bin/true"], [/* 47 vars */]) = 0

См. также Почему bash не создает подоболочку для простых команд?

8
27.01.2020, 20:15

Теги

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