2013-04-11 12 views
3

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

Когда я использую компилятор языка в командной строке, когда я типа куб.см [имя файла], я полагаю, что оболочка использует вилка() Системный вызов дублировать его процесс и затем Exec() системный вызов загрузит компилятор cc, исполняемый в ключевое изображение дочернего процесса. Затем дочерний процесс , содержащий исполняемый файл cc, будет выполнять свою работу, пока ожидает, что родительский процесс, выполняющий оболочку, ждет или нет. Это правильно?

Что относительно команд оболочки, таких как cp, mv, ls и другие. Кто они такие? - это исполняемые программы, которые также будут выполняться в новом дочернем процессе , выложенном оболочкой? Что относительно сценариев оболочки? Предположим, я создаю простой скрипт как этот (пожалуйста игнорировать ошибки, я не знаю, как это сделать еще):

echo "Hello" 

date 

echo 

cc -o test file1.c file2.c file3.c 

, а затем я выполнить этот сценарий с помощью командной строки. Будет ли в командной строке fork() новый процесс и exec() этот скрипт в новом процессе ? И тогда будет ли этот новый процесс, содержащий скрипт fork() других процессов для выполнения даты, компилятора cc и т. Д.?

Надеюсь, это не звучит слишком запутанно, потому что я = /.

ответ

5

Да! У тебя есть идея.

Когда я использую компилятор языка в командной строке, когда я печатаю куб.см [имя файла], я полагаю, что оболочка использует системный вызов вилка(), чтобы дублировать его процесс и затем Exec() системный вызов загрузит исполняемый компилятор cc в ключевое изображение дочернего процесса. Тогда дочерний процесс, содержащий исполняемый файл cc, выполнит свою задачу, пока родительский процесс, выполняющий оболочку, ждет или нет. Это правильно?

Это верно. Родительский процесс (оболочка) вызывает wait() на PID ребенка и ждет его выхода.

Что относительно команд оболочки, таких как cp, mv, ls и другие. Кто они такие? это исполняемые программы, которые также будут выполняться в новом дочернем процессе, выложенном оболочкой?

То же самое. Это двоичные файлы, как и компилятор, и оболочка делает для них то же самое.

Теперь есть несколько команд, которые не являются внешними двоичными файлами, известными как «встроенные». Это команды, которые оболочка распознает сама и не требует вызова внешнего двоичного файла. Зачем?

  • Некоторые из них имеют специальный синтаксис, как if и while, и поэтому при необходимости должны быть встроены в корпус.
  • Некоторые, например cd и read, изменяют состояние процесса оболочки и поэтому должны быть встроенными. (Невозможно, чтобы внешний двоичный файл изменил текущий каталог оболочки, поскольку разветвленные процессы могут изменять только их собственный PWD, а не их родительский.)
  • Другие, такие как echo и printf, могут быть отдельными двоичными файлами и просто выполняться оболочкой.

Вот полный список Баш встроенных команд, которые я получил от ввода help:

job_spec [&]               history [-c] [-d offset] [n] or history -anrw [filename] or histor> 
((expression))              if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [> 
. filename [arguments]            jobs [-lnprs] [jobspec ...] or jobs -x command [args] 
:                  kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill> 
[ arg... ]               let arg [arg ...] 
[[ expression ]]              local [option] name[=value] ... 
alias [-p] [name[=value] ... ]          logout [n] 
bg [job_spec ...]              mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callbac> 
bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r k> popd [-n] [+N | -N] 
break [n]                printf [-v var] format [arguments] 
builtin [shell-builtin [arg ...]]          pushd [-n] [+N | -N | dir] 
caller [expr]               pwd [-LP] 
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac   read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars> 
cd [-L|[-P [-e]]] [dir]            readarray [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callb> 
command [-pVv] command [arg ...]          readonly [-aAf] [name[=value] ...] or readonly -p 
compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W w> return [n] 
complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G gl> select NAME [in WORDS ... ;] do COMMANDS; done 
compopt [-o|+o option] [-DE] [name ...]        set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...] 
continue [n]               shift [n] 
coproc [NAME] command [redirections]         shopt [-pqsu] [-o] [optname ...] 
declare [-aAfFgilrtux] [-p] [name[=value] ...]      source filename [arguments] 
dirs [-clpv] [+N] [-N]            suspend [-f] 
disown [-h] [-ar] [jobspec ...]          test [expr] 
echo [-neE] [arg ...]             time [-p] pipeline 
enable [-a] [-dnps] [-f filename] [name ...]       times 
eval [arg ...]              trap [-lp] [[arg] signal_spec ...] 
exec [-cl] [-a name] [command [arguments ...]] [redirection ...]  true 
exit [n]                type [-afptP] name [name ...] 
export [-fn] [name[=value] ...] or export -p       typeset [-aAfFgilrtux] [-p] name[=value] ... 
false                 ulimit [-SHacdefilmnpqrstuvx] [limit] 
fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]  umask [-p] [-S] [mode] 
fg [job_spec]               unalias [-a] name [name ...] 
for NAME [in WORDS ... ] ; do COMMANDS; done       unset [-f] [-v] [name ...] 
for ((exp1; exp2; exp3)); do COMMANDS; done       until COMMANDS; do COMMANDS; done 
function name { COMMANDS ; } or name() { COMMANDS ; }    variables - Names and meanings of some shell variables 
getopts optstring name [arg]           wait [id] 
hash [-lr] [-p pathname] [-dt] [name ...]        while COMMANDS; do COMMANDS; done 
help [-dms] [pattern ...]            { COMMANDS ; } 

Помимо встроенных команд есть также функции и псевдонимы. Это способы определения новых функциональных возможностей без необходимости создавать отдельные скрипты/двоичные файлы.

uppercase() { 
    tr '[:lower:]' '[:upper:]' <<< "$*" 
} 

alias ls='ls --color=auto -F' 

Функции и псевдонимы обычно для удобства или для добавления дополнительной функциональности.

Что относительно сценариев оболочки? ... Будет ли в командной строке fork() новый процесс и exec() этот скрипт в новом процессе? И тогда будет ли этот новый процесс, содержащий скрипт fork() других процессов для выполнения даты, компилятора cc и т. Д.?

Да, точно вправо. Когда запускается сценарий оболочки, родительская оболочка виляет дочерний процесс, и там работает скрипт. Команды в скрипте и, следовательно, отброшены от этого дочернего процесса; они являются внуками оригинальной раковины.

+0

Отличное объяснение, спасибо –

2

Когда вы выполняете shellscript, он откатывается и создает новую оболочку, интерпретируя каждую команду через отдельный механизм fork/exec. Однако есть некоторые встроенные оболочки, например, эхо может быть встроено в некоторые оболочки, даже если оно доступно в качестве исполняемого файла в/usr/bin. cp и mv - действительно исполняемые файлы, выполняемые с помощью механизма fork/exec. Одна вещь, которую вы, возможно, пропустили, состоит в том, что исполняемые файлы должны быть в каталоге, содержащемся в вашей переменной PATH. Попробуйте переименовать исполняемый файл исполняемого кода hello world в вашем текущем каталоге как ls и укажите свой текущий каталог (.) Как первый в своем пути. Вы также можете узнать об исполняемых файлах с помощью команд type и which.

+0

Интересно..Я не знал об этих переменных PATH ... спасибо! –