쉘 스크립트 mktemp, 임시 명명 된 파이프를 생성하는 가장 좋은 방법은 무엇입니까?


30

으로 임시 파일을 만드는 것이 가장 좋다는 것을 알고 mktemp있지만 명명 된 파이프는 어떻습니까?

가능한 한 POSIX를 준수하는 것을 선호하지만 Linux 만 허용됩니다. 내가 글을 쓰는 것처럼, Bashisms을 피하는 것은 나의 유일한 어려운 기준이다 dash.

답변:


41
tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"

기존 파일 또는 심볼릭 링크에 의해 하이재킹되기 쉬운 일반 파일 생성과 달리 네임 파이프 생성 mkfifo또는 기본 기능 은 지정된 위치에 새 파일을 생성하거나 실패합니다. 같은 뭔가 : >foo의 공격자가 출력을 예측할 수 있다면 있기 때문에 안전하지 않은 mktemp다음 공격자가 자신의 목표 파일을 만들 수 있습니다. 그러나 mkfifo foo그러한 시나리오에서는 실패 할 것입니다.

완전한 POSIX 이식성이 필요한 경우 mkfifo -m 600 /tmp/myfifo하이재킹에 안전하지만 서비스 거부가 발생하기 쉽습니다. 강력한 임의 파일 이름 생성기에 액세스하지 않으면 재 시도를 관리해야합니다.

임시 파일과 관련된 미묘한 보안 문제를 신경 쓰지 않으면 간단한 규칙을 따를 수 있습니다. 개인 디렉터리를 만들고 모든 것을 보관하십시오.

tmpdir=
cleanup () {
  if [ -n "$tmpdir" ] ; then rm -rf "$tmpdir"; fi
  if [ -n "$1" ]; then kill -$1 $$; fi
}
tmpdir=$(mktemp -d)
trap 'cleanup' EXIT
trap 'cleanup HUP' HUP
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
mkfifo "$tmpdir/pipe"

실제로 어제 일찍이 솔루션을 이미 내 솔루션으로 선택했습니다. 누군가가 게시했는지 또는 더 나은지를 확인하기 위해 기다리고있었습니다. 나는 또한 내 경우에는 dir이 갈 길이라고 느꼈다. 어쨌든 ... 도와 주셔서 감사합니다. 감사합니다.
JM 베커

1
trap 명령이 아니어야합니까 trap "rm -rf '$tempdir'" EXIT HUP INT TERM? 트랩 자체 변수 확장을 할 수 있습니까?
6시

@Six 트랩이 트리거 될 때가 아니라 명령이 평가 $tempdir될 때 명령이 확장 됩니다 trap. 이 경우 값이 tempdir작은 따옴표 를 포함 하면 코드가 끔찍하게 부서지는 것을 제외하고는 아무런 차이가 없습니다 . 내 코드는 항상 작동합니다.
Gilles 'SO- 악마 그만'

@Gilles 멋진 기능입니다. 운이없는 작은 따옴표 예제를 시도 했으므로 트랩이 런타임에 변수를 평가할 수 없다고 생각했습니다. 내 $tempdir로컬에 선언 된 것으로 나타 났 으며 트랩에 액세스하려면 전역 적으로 정의해야합니다. 이제 이해가
Six

1
@Gilles ... $tempdir 이 변경되지 않는 한 기본적으로 모든 목적에 허용됩니다. 동일한 임시 이름을 사용하여 여러 임시 파일 / 디렉토리를 만들지 않도록주의하십시오.
MestreLion

3

보다 안전한 대안은 mktemp디렉토리를 안전하게 생성 한 다음 명명 된 파이프를 해당 디렉토리 rm -R $dir에 넣고 마지막에 제거하는 것입니다.


mktemp@Gilles는 이미 유일하게 받아 들일 수있는 대답이므로 디렉토리 에서 FIFO를 만들 것을 선택 했습니다.
JM Becker

2

"드라 이런"옵션을 사용하십시오.

mkfifo $(mktemp -ut pipe.XXX)

1
매뉴얼 페이지에 따르면, -u옵션 사용은 "권장되지 않습니다".
dogbane

@dogbane 그래서의 사용 -t이지만, 안정적으로 작동하는 한 계속 사용할 것입니다.
polemon

죄송합니다. -t낙담 했다는 말은 어디에 있습니까?
dogbane

2
@ dogbane 어떤 식 으로든 중요 하다면mkstemp() 함수 ( linux.die.net/man/3/mkstemp )를 호출하여 작은 C 응용 프로그램을 만들 것 입니다. -t스위치는, 그것이 낙담하지 않는 -p, 내 나쁜.
polemon

1

mktemp임시 파일을 생성 한 다음 삭제하고 동일한 이름을 가진 명명 된 파이프를 생성하는 데 사용할 수 있습니다 .

예를 들면 다음과 같습니다.

TMPPIPE=$(mktemp -t pipe.XXX) && {
    rm -f $TMPPIPE
    mkfifo $TMPPIPE
}

$TMPPIPEbefore를 삭제하면 mkfifo관련된 '안전하지 않은'문제를 피할 수 TMPPIPE=`mktemp -u` ; mkfifo $TMPPIPE있습니까?
JM Becker

1
@TechZilla mkfifo는 쉘에서 일반적인 정기적 인 파일 작성과 달리 실제로 안전합니다. 그렇지 않은 경우 파일을 만든 다음 삭제해도 전혀 도움이되지 않습니다 (실제로 파일 이름을 추측하지 않아도 해커의 작업을 크게 촉진시킵니다). 따라서 dogbane의 답변은 효과가 있지만 중간 파일 생성은 쓸모없는 합병증입니다.
Gilles 'SO- 악한 중지'

1
@Gilles, mktemp맨 페이지에서 -u'안전하지 않은'옵션 이라는 것을 알고 있습니까?
JM Becker

@ dogbane, 나는 당신의 대답에 투표하고 내가 느낀 의견은 견고했습니다. 어제 이미이 작업을 완료했습니다. 누군가 누군가 내 솔루션을 게시했을 때 또는 더 나은 솔루션을 게시 할 때까지 기다리고있었습니다. 그래서 내가 사용했지만 mktemp -d여전히 입력에 대한 몇 가지 포인트가 있습니다. 모든 도움을 주셔서 감사합니다. 정말 감사합니다!
JM 베커

1
@TechZilla mktemp -u는 일반 파일을 만들 때 안전하지 않습니다. 서비스 거부에 대한 보호 기능을 제공하기 때문에 (파일 이름이 충분히 예측할 수없는 경우) 공격자가 프로그램에 따라 파일을 만들지 못합니다. 일반 파일 대신 fifo를 만드는 것은 매뉴얼 페이지에서 다루지 않는 드문 사용 사례입니다.
Gilles 'SO- 악의를 멈추십시오'

0

두 개의 개별 프로세스가 이름으로 파이프에 액세스 할 수있는 Unix를 사용 mkfifo하거나 mknod유닉스에서 사용합니다. 한 프로세스는 독자로, 다른 프로세스는 작가로 열 수 있습니다.

mkfifo my_pipe
gzip -9 -c < my_pipe > out.gz
cat file > my_pipe

명명 된 파이프는 다른 파일과 마찬가지로 삭제할 수 있습니다.

rm my_pipe

mkfifo --mode=0666 /tmp/namedPipe
gzip --stdout -d file.gz > /tmp/namedPipe

NamedPipe는 한 번만 읽기 위해 일반 파일로 사용될 수 있습니다.

http://www.linuxjournal.com/article/2156


2
명명 된 파이프 및에 대해 완전히 알고 mkfifo있습니다. 임시 명명 된 파이프 에 대한 내 질문은 mkdir임시 디렉토리 작성을 다루는 것 이상 으로 다루지 않습니다 .
JM Becker

2
명명 된 파이프 mktemp안전하게 만드는 문제를 어떻게 해결 합니까?
camh

1
오, 가장 좋은 방법은 / tmp 아래에 파일을 작성하는 것입니다. 파일은 정의에 따라 임시 파일이며 시스템이 재부팅되면 해제됩니다. 또는 더 좋은 방법은 mktemp결과 자체 에서 명명 된 파이프를 생성하는 셸 함수를 사용하는 것입니다 (물론 임시 파일을 먼저 삭제 한 다음 mkfifo동일한 방식으로 실행 ). mktemp또한 임시 디렉토리를 만드는 데 사용될 수 있습니다 -t -d.
Nikhil Mulley
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.