When creating directories, mkdir -m <mode> <dir> provides for creating one or more directories with the given mode/permissions set (atomically).
Is there an equivalent for creating files, on the command line?
Something akin to:
open("file", O_WRONLY | O_APPEND | O_CREAT, 0777);
Is using touch followed by a chmod my only option here?
Edit: After trying out teppic’s suggestion to use install, I ran it through strace to see how close to atomic it was. The answer is, not very:
$ 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
...
Still, it’s a single shell command and one I didn’t know before.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You could use the install command (part of GNU coreutils) with a dummy file, e.g.
install -b -m 755 /dev/null newfile
The -b option backs up newfile if it already exists. You can use this command to set the owner as well.
Method 2
touch always creates the file if it doesn’t exist, always follows symbolic links, and always makes the file non-executable. You can decide the read and write bits through the umask.
(umask 077; touch file) # creates a 600 (rw-------) file (umask 002; touch file) # creates a 664 (rw-rw-r--) file
“Safe” atomic file creation (in particular, with O_NOFOLLOW) is not possible with traditional shell tools. You can use sysopen in perl. If you have the BSD-inspired mktemp utility, it creates a file atomically with O_NOFOLLOW; you’ll have to to call chmod afterwards if the default mode of 600 is not the right one.
Method 3
Building on @teppic’s answer, if you want to create the file with content and mode at the same time (bash):
install -m 755 <(echo commands go here) newscript
<() places the output into a temporary file, see Process-Substitution
Method 4
I have a bash script in my home directory /home/anthony/touchmod.sh containing:
#!/bin/bash touch "$2" chmod "$1" "$2"
So if I need to create readme.txt with 644 permissions I can type:
~/touchmod.sh 644 readme.txt
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0