Magia!
Em particular, o shell fork(2)
; isso resulta em duas cópias (na maior parte) idênticas do processo shell; Notavelmente, o processo de shell filho herda uma cópia da entrada padrão do processo de shell pai:
* The child inherits copies of the parent’s set of open file descrip-
tors. Each file descriptor in the child refers to the same open
file description (see open(2)) as the corresponding file descriptor
in the parent. This means that the two descriptors share open file
status flags, current file offset, and signal-driven I/O attributes
(see the description of F_SETOWN and F_SETSIG in fcntl(2)).
Em seguida, o processo do shell filho chamará exec(3)
para iniciar o java
, ou seja, o O processo de shell filho substitui o próprio por java
. Por meio dessa chamada java
obtém as cópias dos descritores de arquivos herdados do pai e pode agir na entrada padrão transmitida para ele.
(Pode haver complicações se um sinalizador "close on exec" estiver definido em um descritor de arquivo, mas esse não é o padrão para os padrões, como a entrada padrão.)
Além disso, se o shell pai não precisar ficar na memória enquanto java
estiver em execução, o código pode ser gravado como:
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
exec java -jar $DIR/../bin-java/opsin/opsin.jar ${@:1}
Para que java
substitua o processo de shell pai em vez de deixar um processo de shell desnecessariamente atrasado na memória.
Para mais detalhes, a Programação Avançada no Ambiente Unix (APUE) tem alguns capítulos sobre as várias chamadas do sistema fork, exec, dup e pipe envolvidas.