명령줄에 설정된 권한으로 파일을 생성할 수 있나요?

명령줄에 설정된 권한으로 파일을 생성할 수 있나요?

디렉토리를 생성할 때 mkdir -m <mode> <dir>지정된 모드/권한 세트를 사용하여 하나 이상의 디렉토리를 (원자적으로) 생성하도록 제안합니다.

명령줄에서 파일을 생성하는 것과 동등한 방법이 있습니까?

비슷하다:

open("file", O_WRONLY | O_APPEND | O_CREAT, 0777);

touch여기서 힐을 사용하는 것이 chmod유일한 옵션입니까?


편집하다:teppic의 제안을 시도한 후 install실행하여 strace원자에 얼마나 가까운지 확인했습니다. 대답은 실제로는 그렇지 않습니다.

$ strace install -m 777 /dev/null newfile
...
open("newfile", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
fstat(4, {st_mode=S_IFREG|0666, st_size=0, ...}) = 0
...
fchmod(4, 0600)                         = 0
close(4)                                = 0
...
chmod("newfile", 0777)                  = 0
...

그러나 이는 단지 쉘 명령일 뿐이며 이전에는 알지 못했던 명령입니다.

답변1

install다음과 같은 더미 파일과 함께 명령을 사용할 수 있습니다 .

install -b -m 755 /dev/null newfile

옵션이 이미 존재하는 경우 -b백업이 생성됩니다. newfile이 명령을 사용하여 소유자를 설정할 수도 있습니다.

Linux에서는 일반적으로 GNU의 일부입니다.핵심 도구또는바쁜 상자, 그러나 4.2BSD 파생 시스템에서도 사용할 수 있습니다.FreeBSD,네트워크BSD또는오픈BSD.

답변2

touch파일이 없으면 항상 파일이 생성되고 심볼릭 링크가 항상 따라가며 파일은 항상 실행 불가능 상태가 됩니다. 읽기 및 쓰기 비트를 다음과 같이 결정할 수 있습니다.마스크.

(umask 077; touch file)  # creates a 600 (rw-------) file
(umask 002; touch file)  # creates a 664 (rw-rw-r--) file

O_NOFOLLOW기존 셸 도구를 사용하여 "안전한" 원자 파일을 만드는 것은 불가능합니다(특히 . sysopen펄에서 사용할 수 있습니다 . BSD에서 영감을 받은 유틸리티가 있는 경우 다음을 사용하여 mktemp자동으로 파일을 생성 합니다. 기본 모드 600이 올바르지 않으면 O_NOFOLLOW나중에 다시 호출해야 합니다.chmod

답변3

@teppic 기준답변, 콘텐츠와 패턴이 모두 포함된 파일을 생성하려는 경우(bash):

install -m 755 <(echo commands go here) newscript

<()출력을 임시 파일에 넣으십시오.프로세스 교체

답변4

표준 도구로는 실제로 이 작업을 수행할 수 없을 것 같지만 Python 인터프리터에 액세스할 수 있다면 다음과 같이 수행할 수 있습니다.

python3 -c 'import os, sys, shutil; shutil.copyfileobj(sys.stdin, open("filename.txt", "w", opener=lambda name, flag: os.open(name, flag, mode=0o631)))' <<< "file_content"

확장되면 Python 스크립트는 기본적으로 다음을 수행합니다.

import os, sys, shutil
file_opener = lambda name, flag: os.open(name, flag, mode=0o631)
dest = open("filename.txt", "w", opener=file_opener)
shutil.copyfileobj(sys.stdin, dest)

다른 스크립팅 언어 해석기의 툴킷에도 비슷한 것이 있을 수 있습니다.

출력 strace:

$ strace python3 -c 'import os, sys, shutil; shutil.copyfileobj(sys.stdin, open("filename.txt", "w", opener=lambda name, flag: os.open(name, flag, mode=0o631)))' <<< "file_content"
...
openat(AT_FDCWD, "filename.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0631) = 3
ioctl(3, FIOCLEX)                       = 0
newfstatat(3, "", {st_mode=S_IFREG|0631, st_size=0, ...}, AT_EMPTY_PATH) = 0
ioctl(3, TCGETS, 0x7ffe4fce65e0)        = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
ioctl(3, TCGETS, 0x7ffe4fce6430)        = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
brk(0x55c88d356000)                     = 0x55c88d356000
read(0, "file_content\n", 65536)        = 13
brk(0x55c88d346000)                     = 0x55c88d346000
read(0, "", 65523)                      = 0
read(0, "", 65536)                      = 0
write(3, "file_content\n", 13)          = 13
...

또는 원자성에 관심을 갖는 유일한 이유가 다른 사용자로 실행되는 적대적인 프로세스에서 파일 내용을 읽는 것을 방지하고 원자성 자체를 사용할 필요가 없는 경우 open(..., mode)하위 프로세스에서 umask를 777로 설정할 수 있습니다. 모든 사람의 권한을 거부하기 위해 파일이 처음 생성되는 방식은 다음과 같습니다.

$ (umask 777; <<< "file_content" > filename.txt)
$ ls -lah filename.txt
---------- 1 lieryan lieryan 13 Sep  8 15:58 filename.txt

그런 다음 즉시 올바른 값으로 파일 권한을 설정하십시오.

$ chmod 631 filename.txt

또는 다음과 같이 정리하세요.

$ (umask 777; <<< "file_content" > filename.txt; chmod 631 filename.txt)

이는 동일한 사용자로 실행되는 다른 프로세스의 경쟁 조건에 여전히 취약하지만, 이를 걱정해야 한다면 아마도 잘못된 것에 대해 걱정하고 있는 것입니다.

관련 정보