Mecanismo de garfo e exec

0

Estou lendo sobre o mecanismo fork & exec no Linux. Aqui estão minhas perguntas no tópico.

  1. Significa que a digitação de um comando simples como ls no prompt de comando transforma o processo bash em fork (duplica-se) e emite uma chamada exec para substituir o código bash clonado pelo código de comando ls? / li>
  2. Com relação ao exemplo acima e de acordo com o documento: %código% Isso significa que o processo de comando child process has the same environment as its parent teria acesso a todas as variáveis de ambiente definidas até agora no bash?
  3. O mecanismo se aplica apenas a binários como comandos incorporados ou scripts de shell também?
por Mulligan 23.01.2017 / 11:50

2 respostas

1

  1. Não, ele gera /usr/bin/ls como um processo filho. Você pode querer brincar com strace se estiver interessado neste tipo de coisas:

    [foo@turtle ~]$ strace -f -eexecve -o bash.strace bash
    [foo@turtle ~]$ ls
    bash.strace
    [foo@turtle ~]$ exit
    [foo@turtle ~]$ cat bash.strace 
    26213 execve("/usr/bin/bash", ["bash"], [/* 37 vars */]) = 0
    26214 +++ exited with 0 +++
    26213 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26214, si_uid=10003, si_status=0, si_utime=0, si_stime=0} ---
    26230 execve("/usr/bin/ls", ["ls", "--color=auto"], [/* 37 vars */]) = 0
    26230 +++ exited with 0 +++
    26213 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26230, si_uid=10003, si_status=0, si_utime=0, si_stime=0} ---
    26213 +++ exited with 0 +++
    
  2. Sim, é mais ou menos o tipo de diferença: se é exportado ou não:

    [foo@turtle ~]$ DIR_I_WANT_TO_LS=/home/foo 
    [foo@turtle ~]$ ls $DIR_I_WANT_TO_LS
    bar  bash.strace  ls_from_a_script.sh
    [foo@turtle ~]$ set -x
    [foo@turtle ~]$ ls $DIR_I_WANT_TO_LS
    bar  bash.strace  ls_from_a_script.sh
    [foo@turtle ~]$ ./ls_from_a_script.sh 
    $DIR_I_WANT_TO_LS=
    bar  bash.strace  ls_from_a_script.sh
    $DIR_I_WANT_TO_LS=/home/foo/bar
    [foo@turtle ~]$ export DIR_I_WANT_TO_LS
    [foo@turtle ~]$ ./ls_from_a_script.sh 
    $DIR_I_WANT_TO_LS=/home/foo
    bar  bash.strace  ls_from_a_script.sh
    $DIR_I_WANT_TO_LS=/home/foo/bar
    
  3. Não, funciona perfeitamente com qualquer programa (binário, shell, ruby, python, lua, nó ...). Os últimos geralmente têm uma estrutura chamada frequentemente de ENV para isso.

por 23.01.2017 / 13:05
0

Does it mean that typing a simple command like ls at command prompt makes the bash process to fork (duplicates itself) and then issue an exec call to substitute the cloned bash code with ls command code?

Basicamente sim. Embora os detalhes técnicos possam variar:

  • Em sistemas operacionais modernos, fork () é rápido devido a copy-on-write. Mas em alguns sistemas mais antigos, cada fork tinha que fazer uma cópia completa da memória do processo, então shells usavam vfork (2) que apenas criou um novo processo mas compartilhou a mesma memória.

  • (No Linux, a função fork (3) na libc na verdade usa o clone (2) syscall. O resultado final ainda é o mesmo.)

  • A libc tem várias funções exec… (3) , que todos traduzem para o execve (2) syscall.

Regarding the exaple above and according to the doc: child process has the same environment as its parent does it mean that ls command process would have an access to all the enviroment variables defined so far in the bash?

Ele teria acesso a uma cópia dessas variáveis de ambiente. (Então, se ls fizer alguma alteração, eles não subirão).

Note que nem todas as variáveis bash são automaticamente variáveis ambiente - somente aquelas explicitamente 'exportadas' para o ambiente. (Você pode usar declare -p para ver todas as variáveis, exportadas ou não.)

Does the mechanism applies only to binaries like build-in commands or to shell scripts too?

Também se aplica a scripts de shell - o kernel considera os scripts com #! executável e passa-os para qualquer "intérprete" especificado na linha #! .

(o Linux também tem "binfmt_misc" que permite definir e executar formatos personalizados - por exemplo, pode ser feito para executar o .exe via Wine.)

Embora se o kernel rejeitar a chamada exec, algumas shells ainda tentarão executar o script manualmente executando / bin / sh com esse script. (Na verdade, às vezes isso é feito até mesmo pela libc - há uma menção no exec(3) manpage da glibc.)

    
por 23.01.2017 / 15:14