/tmp
스크립트를 실행할 때 디렉터리에 임시 파일을 만들고 싶습니다 .
스크립트를 실행한 후 스크립트가 스크립트를 지웁니다.
쉘 스크립트에서 이를 어떻게 수행합니까?
답변1
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"
파일 설명자를 열고 삭제하면 스크립트가 종료될 때(종료 및 충돌 포함) 파일이 삭제되도록 할 수 있습니다. /proc/$PID/fd/$FD
파일 설명자가 열려 있는 한 파일은 계속 사용 가능합니다(스크립트의 경우, 실제로 다른 프로세스의 경우는 아니지만 해결 방법). 파일이 닫히면(프로세스가 종료될 때 커널이 자동으로 이 작업을 수행함) 파일 시스템이 파일을 삭제합니다.
# create temporary file
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
# create file descriptor 3 for writing to a temporary file so that
# echo ... >&3 writes to that file
exec 3>"$tmpfile"
# create file descriptor 4 for reading from the same file so that
# the file seek positions for reading and writing can be different
exec 4<"$tmpfile"
# delete temp file; the directory entry is deleted at once; the reference counter
# of the inode is decremented only after the file descriptor has been closed.
# The file content blocks are deallocated (this is the real deletion) when the
# reference counter drops to zero.
rm "$tmpfile"
# your script continues
: ...
# example of writing to file descriptor
echo foo >&3
# your script continues
: ...
# reading from that file descriptor
head -n 1 <&4
# close the file descriptor (done automatically when script exits)
# see section 2.7.6 of the POSIX definition of the Shell Command Language
exec 3>&-
답변2
mktemp
임시 파일을 만드는 데 사용됩니다 . 이 유틸리티는 생성된 파일의 전체 경로를 반환합니다.
temp_file=$(mktemp)
또는 임시 생성목차:
temp_dir=$(mktemp -d)
스크립트가 끝나면 임시 파일이나 디렉터리를 삭제할 수 있습니다.
rm "${temp_file}"
rm -r "${temp_dir}"
참고: 인수로 지정된 디렉터리에 mktemp
파일을 생성합니다 . 추가 옵션과 동작을 수정하는 방법은 유틸리티 설명서를 참조하세요./tmp
--tmpdir
답변3
일부 쉘에는 내장 기능이 있습니다.
다루기 힘든
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.
Here-documents 또는 here-strings는 bash
5.1 이전 버전에서 zsh
삭제된 임시 파일로 구현되었습니다 (1970년대 후반에 here-document가 도입되었을 때 Bourne 쉘의 경우처럼).
그렇다면 다음과 같이 하세요.
exec 3<<< test
파일 설명자 3은 삭제된 임시 파일이 포함된 파일에 연결됩니다 test\n
.
다음을 통해 내용을 얻을 수 있습니다.
cat <&3
Linux에서는 파일을 읽거나 쓸 수도 있지만 /dev/fd/3
bash 버전 5.0에서는 먼저 파일에 대한 쓰기 권한을 복원해야 합니다(bash는 해당 버전에서 명시적으로 이를 제거했습니다).
$ exec 3<<< test
$ cat <&3
test
$ chmod u+w /dev/fd/3 # only needed in bash 5.0
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo
(일부 다른 쉘은 파이프를 사용하거나 /dev/null
여기 문서가 비어 있으면 사용할 수 있습니다).
POSIX
POSIX 유틸리티 가 없습니다 mktemp
. 그러나 POSIX는mkstemp(template)
응용 프로그래밍 인터페이스, 표준 유틸리티는 m4
동일한 이름의 m4 함수를 사용하여 이 API를 노출합니다.mkstemp()
mkstemp()
함수가 호출될 때 존재하지 않는 것으로 보장되는 임의의 부분이 포함된 파일 이름을 제공합니다. 경쟁 없는 방식으로 권한 0600을 사용하여 파일을 생성합니다.
따라서 다음과 같이 할 수 있습니다.
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
하지만 종료 시 정리 작업을 처리해야 하지만 파일을 정해진 횟수만큼 쓰고 읽어야 하는 경우 위의 here-doc/here-char처럼 문자열 메서드를 생성한 후 열고 삭제할 수 있습니다. :
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
한 번의 읽기를 위해 파일을 연 다음 읽기 사이에 되감을 수 있지만 rewind( ) 작업을 수행하는 POSIX 유틸리티가 없으므로 POSIX 스크립트( ( 내장) 및 ( 연산자) lseek()
에서는 쉽게 수행할 수 없습니다. 자유롭게 그렇게 할 수 있습니다).zsh
sysseek
ksh93
<#((...))
답변4
다음은 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