O Subshell não cria um processo separado

3

Eu tenho um script ./scr .

abc@~ $ cat scr
#!/bin/bash
ps
echo '-------'
echo "$(ps)"

abc@~ $ 

Meu objetivo é descobrir como os subprocessos são criados. Até onde eu sei, a parte $(...) deve criar uma subshell e, portanto, um novo processo. Portanto, o número de processos na segunda chamada de ps deve ser maior.

Isso é exatamente como é se eu fonte o script no shell atual:

abc@~ $ . scr
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
-------
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1785 ttys000    0:00.00 -bash
abc@~ $ 

No entanto, ao iniciar em um shell de interpretação, o número de processos não difere:

abc@~ $ ./scr
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1790 ttys000    0:00.00 /bin/bash ./scr
-------
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1790 ttys000    0:00.00 /bin/bash ./scr
abc@~ $ 

Por que isso acontece?

Da mesma forma, por que ps fornece a mesma saída que (ps) ?

abc@~ $ ps
  PID TTY           TIME CMD
 1659 ttys000    0:00.18 -bash
abc@~ $ (ps)
  PID TTY           TIME CMD
 1659 ttys000    0:00.18 -bash
abc@~ $ 

Uma coisa interessante é que a prepending do comando ps com qualquer outro comando força-o a "produzir" o novo processo esperado (produz o processo esperado no script no topo, em ./scr , também). / p>

abc@~ $ (echo 1; ps)
1
  PID TTY           TIME CMD
 1659 ttys000    0:00.20 -bash
 1823 ttys000    0:00.00 -bash
abc@~ $ 

O (ps) é de alguma forma "otimizado" pelo shell? E por que não é, quando originado?

Uma observação: o sistema é na verdade um macOS, mas não espero que ele se comporte diferente nesse caso.

EDITAR:

Como em esta resposta , a subshell parece estar sujeita a otimização e, portanto, não está sendo executada em um shell separado, recém-iniciado, porque aparentemente não é necessário.

Por que é necessário ao executar no shell atual, então ( . scr )?

    
por Dart Dega 26.01.2017 / 08:53

1 resposta

2

A substituição de comandos acontece em " ambiente subshell ", não necessariamente como um completo -subshell -blown; o shell evitará criar um processo inútil se o efeito de ter um ambiente subshell puder ser alcançado sem ele. Se você quiser ver uma subcamada completa, dê algo para fazer que precise de uma subcamada completa; compare:

$ echo "$(ps fax)"
  PID TTY      STAT   TIME COMMAND
  ...
 1317 ?        Ss     0:00 /usr/sbin/sshd -D
 1751 ?        Ss     0:00  \_ sshd: alexp [priv]
 1788 ?        S      0:00      \_ sshd: alexp@pts/0
 1789 pts/0    Ss+    0:00          \_ -bash
 1822 pts/0    R+     0:00              \_ ps fax
  ...
$ echo "$(ps fax; echo)"
  PID TTY      STAT   TIME COMMAND
  ...
 1317 ?        Ss     0:00 /usr/sbin/sshd -D
 1751 ?        Ss     0:00  \_ sshd: alexp [priv]
 1788 ?        S      0:00      \_ sshd: alexp@pts/0
 1789 pts/0    Ss+    0:00          \_ -bash
 1823 pts/0    S+     0:00              \_ -bash
 1824 pts/0    R+     0:00                  \_ ps fax
  ...
    
por 26.01.2017 / 10:22