ディレクトリを作成するときは、mkdir -m <mode> <dir>
指定されたモード/権限セットを使用して1つ以上のディレクトリを(原子的に)作成することをお勧めします。
コマンドラインからファイルを生成するのと同等の方法はありますか?
似ている:
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
答え2
touch
ファイルが存在しない場合は、常にファイルが作成され、シンボリックリンクが常に追従し、ファイルは常に実行不可能になります。読み書きビットは次のように決定できます。マスク。
(umask 077; touch file) # creates a 600 (rw-------) file
(umask 002; touch file) # creates a 664 (rw-rw-r--) file
O_NOFOLLOW
既存のシェルツールを使用して「安全な」アトミックファイルを作成することは不可能です(特に.Perlsysopen
で利用可能です。BSDからインスピレーションを受けたユーティリティがある場合は、次のようにmktemp
自動的にファイルを生成します。)デフォルトモード600が正しいそうでなければ、O_NOFOLLOW
後でもう一度呼び出す必要があります。chmod
答え3
答え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)
これは、同じユーザーで実行されている他のプロセスの競合状態にまだ脆弱ですが、それを心配する必要がある場合は、おそらく間違ったことを心配しています。