opsin
Java 바이너리에 대한 호출만 관리하는 bash 스크립트(라는 이름)가 있습니다 . 모든 매개변수는 ${@:1}
Java 바이너리로 전달됩니다.
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
java -jar $DIR/../bin-java/opsin/opsin.jar ${@:1}
이 바이너리 opsin.jar
도 허용 stdin
하므로 다음을 수행할 수 있습니다.
echo "abcd" | java -jar opsin.jar
하지만 위의 bash 스크립트를 사용하여 동일한 작업을 수행할 수 있습니다.
echo "abcd" | opsin
어떻게 stdin
전달되나요?
java -jar $DIR/../bin-java/opsin/opsin.jar ${@:1}
Bash 스크립트에서?
답변1
마법!
특히 쉘은fork(2)
이는 쉘 프로세스의 두 개의 (대부분) 동일한 복사본을 생성합니다. 특히 하위 쉘 프로세스는 부모 쉘 프로세스의 표준 입력 복사본을 상속합니다.
* 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)).
그러면 서브쉘 프로세스가 호출됩니다.exec(3)
Start java
, 즉 서브쉘 프로세스바꾸다java
이 호출은 상위 java
에서 상속된 파일 설명자의 복사본을 얻고 전달된 표준 입력에 대해 작동할 수 있습니다.
(파일 설명자에 "실행 시 닫기" 플래그가 설정되어 있으면 문제가 발생할 수 있지만 이는 표준 입력과 같은 표준 플래그에 대한 기본 설정이 아닙니다.)
또는 상위 셸이 실행 중에 메모리에 남아 있을 필요가 없으면 java
코드를 다음과 같이 작성할 수 있습니다.
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
exec java -jar $DIR/../bin-java/opsin/opsin.jar ${@:1}
이는 java
셸 프로세스가 불필요하게 메모리에 머무르는 대신 상위 셸 프로세스를 대체합니다.
자세한 내용은 APUE(Advanced 프로그래밍 in Unix 환경)에 관련된 다양한 포크, exec, dup 및 파이프 시스템 호출에 대한 장이 있습니다.