쉘 스크립트에서 임시 파일을 작성하는 방법 . 해당 스크립트를 실행 한

스크립트를 실행하는 동안 /tmp디렉토리에 임시 파일을 만들고 싶습니다 .

해당 스크립트를 실행 한 후에는 해당 스크립트로 정리됩니다.

쉘 스크립트에서 어떻게합니까?



답변

tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"

파일 설명자를 파일로 열고 삭제하여 스크립트가 종료 (킬 (kill) 및 충돌 포함) 할 때 파일이 삭제되도록 할 수 있습니다. /proc/$PID/fd/$FD파일 디스크립터가 열려있는 한 파일 은 스크립트에 사용할 수 있습니다 (실제로 다른 프로세스는 아니지만 해결 방법입니다). 파일 시스템이 닫히면 (프로세스가 종료 될 때 커널이 자동으로 수행함) 파일 시스템이 파일을 삭제합니다.

tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
exec 3>"$tmpfile"
rm "$tmpfile"
: ...
echo foo >&3


답변

mktemp임시 파일 또는 디렉토리를 작성하는 데 사용하십시오 .

temp_file=$(mktemp)

또는 이분법의 경우 :

temp_dir=$(mktemp -d)

스크립트가 끝나면 임시 파일 / dir을 삭제해야합니다.

rm ${temp_file}
rm -R ${temp_dir}

mktemp는 /tmp디렉토리 또는 --tmpdir인수 와 함께 주어진 술집에 파일을 작성합니다 .


답변

mktemp 가있는 시스템을 사용하는 경우 다른 답변으로 사용해야합니다.

POSIX toolchest 사용시 :

umask 0177
tmpfile=/tmp/"$0"."$$"."$(awk 'BEGIN {srand();printf "%d\n", rand() * 10^10}')"
trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
: > "$tmpfile"


답변

일부 쉘에는 기능이 내장되어 있습니다.

zsh

zsh=(...)공정 대체의 형태는 임시 파일을 사용합니다. 예를 들어 =(echo test),가 포함 된 임시 파일의 경로로 확장됩니다 test\n.

$ {cat $file; ls -l /dev/fd/3; echo test2 >&3; cat $file} 3<> ${file::==(echo test)}
test
lrwx------ 1 stephane stephane 64 Jan 30 11:19 /dev/fd/3 -> /tmp/zshMLbER0
test2

명령이 완료되면 해당 파일이 자동으로 제거됩니다.

Linux의 bash / zsh

여기에서 파일 또는 여기 – 문자열의 bash와는 zsh삭제 된 임시 파일로 구현됩니다.

따라서 할 경우 :

exec 3<<< test

파일 디스크립터 3이 포함 된 삭제 된 임시 파일에 연결되어 있습니다 test\n.

다음을 통해 컨텐츠를 얻을 수 있습니다.

cat <&3

Linux의 경우 다음을 통해 해당 파일을 읽거나 쓸 수도 있습니다 /dev/fd/3

$ exec 3<<< test
$ cat <&3
test
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo

(일부 다른 쉘은 파이프를 사용하거나 /dev/nullhere 문서가 비어 있으면 사용할 수 있습니다 ).

POSIX

mktempPOSIX 유틸리티 가 없습니다 . 그러나 POSIX는 mkstemp(template)C API를 지정 하고 m4표준 유틸리티는 mkstemp()동일한 이름으로 m4 함수 를 사용하여 해당 API를 노출합니다 .

mkstemp()함수가 호출 될 때 존재하지 않는 임의 부분이있는 파일 이름을 제공합니다. 레이스가없는 방식으로 권한이 0600 인 파일을 만듭니다.

그래서 당신은 할 수 있습니다 :

tmpfile=$(
  echo 'mkstemp(template)' |
    m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit

그러나 종료시 정리를 처리해야하지만 파일을 고정 된 횟수만큼 읽고 쓸 필요가있는 경우 here-doc / here-와 같이 만든 후 바로 파일을 열고 삭제할 수 있습니다. 위의 문자열 접근 방식 :

tmpfile=$(
  echo 'mkstemp(template)' |
    m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit

# open once for writing, twice for reading:
exec 3> "$tempfile" 4< "$tempfile" 5< "$tempfile"

rm -f -- "$tmpfile"

cmd >&3   # store something in the temp file
exec 3>&- # fd no longer needed

# read the content twice:
cat <&4
cat <&5

한 번 읽기 위해 파일을 열고 두 번의 읽기 사이에서 되감기를 할 수 있지만 되감기 ( lseek())를 수행 할 수있는 POSIX 유틸리티 는 없으므로 POSIX 스크립트 ( zsh( sysseek기본 제공) 및 ksh93( <#((...))연산자) 에서 이식 가능하지 않음 ) 그래도).


답변

Hauke ​​Laging의 라인에서 약간 개선 된 답변이 있습니다.

#!/bin/bash

tmpfile=$(mktemp)  # Create a temporal file in the default temporal folder of the system

# Lets do some magic for the tmpfile to be removed when this script ends, even if it crashes
exec {FD_W}>"$tmpfile"  # Create file descriptor for writing, using first number available
exec {FD_R}<"$tmpfile"  # Create file descriptor for reading, using first number available
rm "$tmpfile"  # Delete the file, but file descriptors keep available for this script

# Now it is possible to work with the temporal file
echo foo >&$FD_W
echo bar >&$FD_W  # Note that file descriptor always concatenates, not overwrites

cat <&$FD_R


답변

일반적으로 임시 파일이있는 워크 플로는 테스트중인 bash 스크립트 때문입니다. 나는 tee그것이 작동하고 있음을 알 수 있고 프로세스의 다음 반복을 위해 출력을 저장하고 싶습니다. 라는 파일을 만들었습니다tmp

#!/bin/bash
echo $(mktemp /tmp/$(date +"%Y-%m-%d_%T_XXXXXX"))

내가 그것을 사용할 수 있도록

$ some_command --with --lots --of --stuff | tee $(tmp)

임의의 값보다 형식이 지정된 날짜 시간을 좋아하는 이유는 내가 방금 만든 tmp 파일을 찾을 수 있기 때문에 다음 번에 이름을 지정할 대상을 생각할 필요가 없습니다. 일하다).


답변