bash에서 임시 파일 만들기


150

bash 스크립트에서 임시 파일을 작성하는 객관적으로 더 나은 방법이 있습니까?

나는 보통 스크립트가 끝날 때 삭제되므로 tempfile-123과 같이 내 마음에 오는 모든 것을 이름을 지정합니다. 현재 폴더에서 가능한 tempfile-123을 덮어 쓰는 것 외에 다른 방법으로 단점이 있습니까? 아니면 더 신중하게 임시 파일을 만들면 어떤 이점이 있습니까?


1
임시 파일을 사용하지 마십시오. 대신 임시 디렉토리를 사용하십시오. 그리고 mktemp를 사용하지 마십시오. 왜 여기를 참조하십시오 codeproject.com/Articles/15956/...이
ceving

17
@ceving 최소한 mktemp 라이브러리 호출과 달리 쉘 명령 mktemp에 적용될 때 그 기사는 단순히 잘못되었습니다. mktemp가 제한적인 umask로 파일 자체를 생성 할 때, 공격자는 공격자와 동일한 계정으로 작동하는 경우에만 작동합니다.이 경우 게임이 이미 손실됩니다. 쉘 스크립팅 세계의 모범 사례는 mywiki.wooledge.org/BashFAQ/062
Charles Duffy

tempfile(1)시스템이있는 시스템 에서도 사용할 수 있습니다 .
추후 공지가있을 때까지 일시 중지되었습니다.

답변:


179

mktemp(1)man 페이지는 상당히 잘 설명 :

전통적으로 많은 쉘 스크립트는 pid를 접미사로하여 프로그램 이름을 임시 파일 이름으로 사용합니다. 이러한 종류의 이름 지정 체계는 예측 가능하며 생성 된 경쟁 조건은 공격자가 이기기 쉽습니다. 여전히 안전하지는 않지만보다 안전한 방법은 동일한 이름 지정 체계를 사용하여 임시 디렉토리를 만드는 것입니다. 이렇게하면 임시 파일이 전복되지 않도록 보장 할 수 있지만 여전히 간단한 서비스 거부 공격이 허용됩니다. 이러한 이유로 mktemp를 대신 사용하는 것이 좋습니다.

스크립트에서 다음과 같은 mktemp를 호출합니다.

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")

작업 할 수있는 임시 디렉토리를 만들고 실제 파일을 읽기 쉽고 유용한 이름으로 안전하게 지정할 수 있습니다.

mktemp표준은 아니지만 많은 플랫폼에 존재합니다. "X"는 일반적으로 임의의 임의성으로 변환되며, 더 많은 것은 아마도 임의성 일 것입니다. 그러나 일부 시스템 (busybox ash)은이 임의성을 다른 시스템보다 더 크게 제한합니다.


그런데 임시 파일의 안전한 생성은 단순한 쉘 스크립팅 이상으로 중요합니다. 그렇기 때문에 파이썬에는 tempfile이 있고 perl에는 File :: Temp , ruby에는 Tempfile 등이 있습니다.


1
-t 옵션은 더 이상 사용되지 않습니다 : gnu.org/software/coreutils/manual/html_node/…
Tibor Vass

7
가장 안전하고 크로스 플랫폼을 사용하는 방법 mktemp은와 basename같이 사용 mktemp -dt "$(basename $0). XXXXXXXXXX"됩니다. 사용하지 않으면 basename다음과 같은 오류가 발생할 수 있습니다 . mktemp : 잘못된 템플릿`/tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX '는 디렉토리 구분 기호를 포함합니다 .
i4niac

7
오타 (추가 공간)는 무시하십시오. mktemp -dt "$(basename $0).XXXXXXXXXX"올바른 방법입니다.
i4niac

3
@ i4niac : 당신이 필요한 것을 인용 $0공간은 OS X의 땅에 많이있다,mktemp -dt "$(basename "$0").XXXXXX"
Orwellophile

11
또한 스크립트 실행이 끝날 때 tempdir을 제거하는 것이 좋습니다.trap "rm -rf $mydir" EXIT
KumZ

43

예, mktemp를 사용하십시오 .

임시 파일을 저장하도록 설계된 폴더 안에 임시 파일을 생성하며 고유 한 이름을 보장합니다. 해당 파일의 이름을 출력합니다.

> mktemp
/tmp/tmp.xx4mM3ePQY
>

19

보고 싶을 수도 있습니다 mktemp

mktemp 유틸리티는 주어진 파일 이름 템플릿을 가져와 고유 한 파일 이름을 생성하기 위해 그 일부를 덮어 씁니다. 템플릿은 /tmp/tfile.XXXXXXXXXX와 같이 몇 개의 'X'가 추가 된 파일 이름 일 수 있습니다. 후행 'X'는 현재 프로세스 번호와 임의 문자의 조합으로 대체됩니다.

자세한 내용은 man mktemp


11

보다 신중한 방법으로 임시 파일을 만들면 어떤 이점이 있습니까?

임시 파일은 일반적으로 /tmp다른 모든 사용자 및 프로세스가 읽기 및 쓰기 액세스 권한을 가진 임시 디렉토리 (예 :와 같은 )에 작성됩니다 (다른 스크립트가 새 파일을 작성할 수 있음). 따라서 스크립트는 올바른 권한으로 사용하는 등의 파일 작성에주의해야합니다 (예 : 소유자 만 읽기 : 참조). help umaskfilename은 쉽게 추측 할 수 없습니다 (이상적으로 무작위). 그렇지 않으면 파일 이름이 고유하지 않으면 동일한 스크립트와 여러 번 실행 된 충돌이 발생할 수 있습니다 (예 : 경쟁 조건)) 또는 일부 공격자는 민감한 정보 (예 : 권한이 너무 열려 있고 파일 이름을 추측하기 쉬운 경우)를 납치하거나 자신의 코드 버전으로 파일을 만들거나 대체 할 수 있습니다 (예 : 명령 또는 SQL 쿼리를 현재 상태에 따라 교체) 저장).


다음 방법을 사용하여 임시 디렉토리를 작성할 수 있습니다.

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"

또는 임시 파일 :

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"

그러나 여전히 예측 가능하며 안전하지 않은 것으로 간주됩니다.

에 따라 man mktemp읽을 수 있습니다 :

전통적으로 많은 쉘 스크립트는 pid를 접미사로하여 프로그램 이름을 임시 파일 이름으로 사용합니다. 이러한 종류의 이름 지정 체계는 예측 가능하며 생성 된 경쟁 조건은 공격자가 이기기 쉽습니다.

따라서 안전을 위해 mktemp명령을 사용하여 고유 한 임시 파일 또는 디렉토리 ( -d) 를 작성 하는 것이 좋습니다 .


2
정확히 무엇을 요구 받았 는가. 그러나 완벽한 솔루션이 될 수 있습니다.
jpbochi

1
@ jpbochi 질문에 대한 답변을 개선했습니다. 도움이되는지 알려주세요.
kenorb

2
실제로 대답을 향상시킵니다. 그래도 내 공감은 이미 너의 것이었다. 더 투표 할 수 없습니다. 내가 가진 한 가지 제안은 무엇을 설명하는 것입니다 ${0##*/}$$에 확장, 또는 그것에 대해 몇 가지 문서에 대한 링크.
jpbochi

0

mktemp 특히 파일을 한동안 사용하려는 경우 가장 다재다능합니다.

다른 명령에 대한 입력으로 파일을 임시로만 필요한 경우 프로세스 대체 연산자를 사용할 수도 있습니다. <()예 :

$ diff <(echo hello world) <(echo foo bar)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.