Когда встроенные команды загружаются в память

11

Скажем, если я наберу cdв моей оболочке. Является ли cdзагружен из памяти в тот момент? Моя интуиция заключается в том, что эти встроенные команды предварительно загружаются в системную память после загрузки ядра, но кто-то настаивал на том, что они загружаются только тогда, когда я действительно вызываю команду (нажмите Enter на оболочке). Не могли бы вы сказать мне, если есть ссылка, которая объясняет это?

Forethinker
источник
1
Я думаю, что этот ответ поможет вам понять, хотя это не совсем дубликат.
CJM
@cjm: Спасибо, это действительно хорошее объяснение для чтения.
Forethinker

Ответы:

9

Скажем, если я наберу CD в моей оболочке. В этот момент загружен CD из памяти? Моя интуиция заключается в том, что эти встроенные команды предварительно загружаются в системную память после загрузки ядра, но кто-то настаивал на том, что они загружаются только тогда, когда я действительно вызываю команду ...

В общих чертах остальные ответы верны - встроенные модули загружаются с оболочкой, автономные загружаются при вызове. Однако очень неуклюжий ласковый «кто-то» может настаивать на том, что это не так просто.

Это обсуждение в некоторой степени о том, как работает ОС, и разные ОС работают по-разному, но я думаю, что в общем случае следующее верно для всех современных * nixes.

Во-первых, «загружен в память» - это неоднозначная фраза; на самом деле мы имеем в виду, что виртуальное адресное пространство отображается в памяти . Это важно, потому что «виртуальное адресное пространство» относится к материалам, которые, возможно, необходимо поместить в память, но на самом деле это не изначально: в основном то, что фактически загружается в память, это сама карта, а карта не является территорией. Территория будет представлять собой исполняемый файл на диске (или в дисковом кеше), и, по сути, большая часть этого, вероятно, не загружается в память при вызове исполняемого файла.

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

Например, вот фрагмент topвывода на linux со ссылкой на bashэкземпляр:

VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                  
113m 3672 1796 S  0.0  0.1   0:00.07 bash   

113 МБ VIRT - это виртуальное адресное пространство, которое отображается в ОЗУ. Но RES - это фактический объем оперативной памяти, потребляемой процессом - всего 3,7 кБ. И из этого часть является частью упомянутой выше общей территории - 1,8 кбайт SHR. Но у меня /bin/bashна диске 930 кБ, и базовый libc, на который он ссылается (разделяемый lib), снова в два раза больше.

Эта оболочка сейчас ничего не делает. Допустим, я вызываю встроенную команду, которая, как мы говорили ранее, уже была «загружена в память» вместе с остальной частью оболочки. Ядро выполняет любой код, начиная с некоторой точки на карте, и, когда оно достигает ссылки на код, который на самом деле не был загружен, оно загружает его - из исполняемого образа на диске - хотя и в более случайном порядке. Смысл в том, что исполняемый файл (будь то оболочка, автономный инструмент или разделяемая библиотека) уже «загружен в память».

Это называется поиском по запросу .

лютик золотистый
источник
9

Ожидая, пока один из тяжеловесов придет и даст полную историческую перспективу, я дам вам более ограниченное понимание.

Встроенные команды , как alias, cd, и echoт.д. , являются частью вашей оболочки ( bash, zsh, kshили любой другой ). Они загружаются одновременно с оболочкой и являются просто внутренними функциями этой оболочки.

Тердон
источник
4

Я выполнил следующий эксперимент, чтобы показать, что встроенные команды фактически загружаются как часть исполняемого кода bash. Следовательно, почему их называют встроенными, но демо-версия всегда лучший способ что-то доказать.

пример

  1. Запустите новую bashоболочку и запишите ее идентификатор процесса (PID):

    $ bash
    $ echo $$
    6402
    
  2. Во втором терминале запустите psкоманду, чтобы мы могли посмотреть, bashначнет ли она занимать дополнительную память:

    $ watch "ps -Fp 6402"
    

    Вывод выглядит так:

    Every 2.0s: ps -Fp 6402                        Sat Sep 14 14:40:49 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml      6402  6349  0 28747  6380   1 14:33 pts/38   00:00:00 bash
    

    ПРИМЕЧАНИЕ. Использование памяти показано здесь в столбцах SZ и RSS.

  3. Запустите команды в оболочке (pid 6402):

    По мере того, как вы cdвокруг, вы заметите, что память действительно увеличивается, но это не потому, что исполняемый файл cdзагружается в память, а потому, что структура каталогов на диске загружается в память. Если вы продолжаете cdзаходить в другие каталоги, вы увидите, что он постепенно увеличивается.

    Every 2.0s: ps -Fp 30208                        Sat Sep 14 15:11:22 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml     30208  6349  0 28780  6492   0 15:09 pts/38   00:00:00 bash
    

    Вы можете сделать более сложные тесты, как это:

    $ for i in `seq 1000`; do cd ..; cd 90609;done
    

    Эта команда перейдет на уровень выше и затем вернется в каталог 90609 1000 раз. При запуске этого, если вы контролируете использование памяти в psокне, вы заметите, что оно не меняется. Во время выполнения чего-то подобного не должно быть замечено никакого дополнительного использования памяти.

  4. Трассирование

    Вот еще один пример того, что мы имеем дело со встроенной функцией, bashа не с исполняемым файлом. При попытке запустить strace cd ..вы получите следующее сообщение:

    $ strace cd ..
    strace: cd: command not found
    
SLM
источник
3

«Встроенная команда» относится к командам, встроенным в оболочку, а не как отдельные программы. lsНапример, на самом деле это не встроенная команда, а отдельная программа. Он будет загружен в оперативную память при вызове, если только он не находится в кеше диска.

Примером встроенной команды может быть printfили cd. Они являются частью оболочки и загружаются вместе с остальной частью оболочки.

По умолчанию никакие команды не загружаются заранее, хотя для этого созданы системы.

wingedsubmariner
источник