다음 기능을 사용하여 테스트했습니다 GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
. 운영 체제는 Ubuntu 18입니다.이 함수는 익명의 FIFO에 필요한 파일 디스크립터 인 단일 매개 변수를 사용합니다.
MakeFIFO() {
local "MakeFIFO_upper=$(ulimit -n)"
if [[ $# -ne 1 || ${#1} -gt ${#MakeFIFO_upper} || -n ${1%%[0-9]*} || 10#$1 -le 2
|| 10#$1 -ge MakeFIFO_upper ]] || eval ! exec "$1<> " <(:) 2>"/dev/null"; then
echo "$FUNCNAME: $1: Could not create FIFO" >&2
return "1"
fi
}
다음 기능을 사용하여 테스트했습니다 GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
. 운영 체제는 macOS High Sierra입니다. 이 함수는 이름이 지정된 FIFO 를 생성 한 프로세스에만 알려진 임시 디렉토리에 생성하여 시작 합니다 . 다음으로 파일 디스크립터가 FIFO로 경로 재 지정됩니다. 마지막으로 FIFO는 임시 디렉토리를 삭제하여 파일 이름에서 연결 해제됩니다. 이것은 FIFO를 익명으로 만듭니다.
MakeFIFO() {
MakeFIFO.SetStatus() {
return "${1:-$?}"
}
MakeFIFO.CleanUp() {
local "MakeFIFO_status=$?"
rm -rf "${MakeFIFO_directory:-}"
unset "MakeFIFO_directory"
MakeFIFO.SetStatus "$MakeFIFO_status" && true
eval eval "${MakeFIFO_handler:-:}'; true'"
}
local "MakeFIFO_success=false" "MakeFIFO_upper=$(ulimit -n)" "MakeFIFO_file="
MakeFIFO_handler="$(trap -p EXIT)"
MakeFIFO_handler="${MakeFIFO_handler#trap -- }"
MakeFIFO_handler="${MakeFIFO_handler% *}"
trap -- 'MakeFIFO.CleanUp' EXIT
until "$MakeFIFO_success"; do
[[ $# -eq 1 && ${#1} -le ${#MakeFIFO_upper} && -z ${1%%[0-9]*}
&& 10#$1 -gt 2 && 10#$1 -lt MakeFIFO_upper ]] || break
MakeFIFO_directory=$(mktemp -d) 2>"/dev/null" || break
MakeFIFO_file="$MakeFIFO_directory/pipe"
mkfifo -m 600 $MakeFIFO_file 2>"/dev/null" || break
! eval ! exec "$1<> $MakeFIFO_file" 2>"/dev/null" || break
MakeFIFO_success="true"
done
rm -rf "${MakeFIFO_directory:-}"
unset "MakeFIFO_directory"
eval trap -- "$MakeFIFO_handler" EXIT
unset "MakeFIFO_handler"
"$MakeFIFO_success" || { echo "$FUNCNAME: $1: Could not create FIFO" >&2; return "1"; }
}
위 기능은 두 운영 체제 모두에서 작동하는 단일 기능으로 결합 될 수 있습니다. 아래는 그러한 기능의 예입니다. 여기서는 익명의 FIFO를 만들려고합니다. 실패하면 명명 된 FIFO가 만들어지고 익명의 FIFO로 변환됩니다.
MakeFIFO() {
MakeFIFO.SetStatus() {
return "${1:-$?}"
}
MakeFIFO.CleanUp() {
local "MakeFIFO_status=$?"
rm -rf "${MakeFIFO_directory:-}"
unset "MakeFIFO_directory"
MakeFIFO.SetStatus "$MakeFIFO_status" && true
eval eval "${MakeFIFO_handler:-:}'; true'"
}
local "MakeFIFO_success=false" "MakeFIFO_upper=$(ulimit -n)" "MakeFIFO_file="
MakeFIFO_handler="$(trap -p EXIT)"
MakeFIFO_handler="${MakeFIFO_handler#trap -- }"
MakeFIFO_handler="${MakeFIFO_handler% *}"
trap -- 'MakeFIFO.CleanUp' EXIT
until "$MakeFIFO_success"; do
[[ $# -eq 1 && ${#1} -le ${#MakeFIFO_upper} && -z ${1%%[0-9]*}
&& 10#$1 -gt 2 && 10#$1 -lt MakeFIFO_upper ]] || break
if eval ! exec "$1<> " <(:) 2>"/dev/null"; then
MakeFIFO_directory=$(mktemp -d) 2>"/dev/null" || break
MakeFIFO_file="$MakeFIFO_directory/pipe"
mkfifo -m 600 $MakeFIFO_file 2>"/dev/null" || break
! eval ! exec "$1<> $MakeFIFO_file" 2>"/dev/null" || break
fi
MakeFIFO_success="true"
done
rm -rf "${MakeFIFO_directory:-}"
unset "MakeFIFO_directory"
eval trap -- "$MakeFIFO_handler" EXIT
unset "MakeFIFO_handler"
"$MakeFIFO_success" || { echo "$FUNCNAME: $1: Could not create FIFO" >&2; return "1"; }
}
다음은 익명의 FIFO를 만든 다음 동일한 FIFO에 일부 텍스트를 쓰는 예입니다.
fd="6"
MakeFIFO "$fd"
echo "Now is the" >&"$fd"
echo "time for all" >&"$fd"
echo "good men" >&"$fd"
아래는 익명의 FIFO의 전체 내용을 읽는 예입니다.
echo "EOF" >&"$fd"
while read -u "$fd" message; do
[[ $message != *EOF ]] || break
echo "$message"
done
다음과 같은 출력이 생성됩니다.
Now is the
time for all
good men
아래 명령은 익명의 FIFO를 닫습니다.
eval exec "$fd>&-"
참조 :
나중에 사용할 수 있도록 익명 파이프 만들기
공개적으로 쓰기 가능한 디렉토리의 파일이 위험한 셸 스크립트 보안 임