Почему 'ls' создается вызовом execve (), а не fork()

Честно говоря, я вообще не вижу смысла в двух обращениях к cd.

Похоже, вы не используете cdкаталог, в который зашли, ни для чего. Вы указываете абсолютный путь для расположения дампа базы данных. Если требуется какой-либо пользовательский файл конфигурации MySQL, он в любом случае будет взят из домашнего каталога пользователя.

Таким образом, вполне вероятно, вы могли бы просто использовать

mysqldump -uroot -p"craft" --add-drop-table craft \
    > ~/../docker-entrypoint-initdb.d/base.sql

независимо от того, из какого каталога вы его запускаете.

0
15.04.2021, 00:24
1 ответ

Вы правильно поняли. Когда вы запускаете strace ls, есть даже два форка. Оболочка разветвляется и использует exec()для запуска strace, а strace делает то же самое для запуска ls.

Вы не видите ветвление в выводе strace, потому что strace выводит все системные вызовы, исходящие из дочернего процесса strace и на тот момент вилка уже произошла:

  1. bashразвилки и трассыstrace

  2. straceвилки

  3. Родительский процесс straceприсоединяется к дочернему процессу для перехвата всех системных вызовов.

    С этого момента вы видите только системные вызовы.

  4. Ребенок straceзапускает ls, используяexecve()

Один из способов увидеть развилки — прикрепить strace"извне":

  • Используйте echo $$для получения идентификатора процесса оболочки
  • Запустите strace -f --attach=PIDс заменой «PID» на идентификатор процесса, указанный выше в другой консоли .
  • Выполнить lsв первой оболочке
  • В другом окне консоли вы увидите все системные вызовы, происходящие в оболочке и разветвленных потомках (, включая вызовы fork()/ clone()).
  • Используйте CTRL+C во второй консоли, чтобы остановить strace.

Следует также упомянуть, что fork()в современных ядрах Linux реализуется с помощью системного вызова clone(), так что вы, вероятно, увидите clone(…)вместо fork()в выводе strace.

4
28.04.2021, 22:52

Теги

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