Can files be created with permissions set on the command line?
When creating directories, mkdir -m
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, ) = 0 . fchmod(4, 0600) = 0 close(4) = 0 . chmod("newfile", 0777) = 0 .
6 Answers 6
You could use the install command 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.
On Linux it’s usually part of GNU coreutils or BusyBox, but it’s also available on systems derived from 4.2BSD, e.g. FreeBSD, NetBSD or OpenBSD.
It’s a useful little command. As its name suggests it’s really designed for installing software compiled from source code, to save having to use chmod, chown, and so forth all the time.
Note that mode 755 is the default permissions of files created with install , so -m 755 is not needed.
@Kusalananda It’s obviously just an example of how to set a mode, since that was the question, not how to set 755.
install does not atomically create files with the given permissions. It calls fchmod() separately. An unauthorised user may open the file between the creation and the permissions change, thus it possible to read contents later that they are not allowed to read (e.g. for a private key file). Thus install should not be used if file permission security is important. (This was edited into the question, but I think it’s good to state it under this answer since it’s currently marked accepted despite not fulfilling the requested «atomic» requirement.)
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.
I was in the process of writing out a more detailed explanation, but the wikipedia articles covers everything just fine.
If only touch had the option of creating executable files, that’s really what I’m after. Then umask could be used to tailor the details. Sadly there is no way with umask and touch to create executables.
@quornian You can’t create a non-empty file atomically anyway. What’s the point of creating an empty executable file atomically? Use touch followed by chmod +x .
You can create non-empty, executables files atomically with. ln or mv. You can always create the file with the right content and permissions in a directory created with umask 077 and move it or ln it afterwards.
Building on @teppic’s answer, if you want to create the file with content and mode at the same time (bash):
With zsh’s sysopen builtin (enabled with zmodload zsh/system ) you can specify the mode with -m , still subject to umask , but you can set it to 0:
zmodload zsh/system (umask 0 && sysopen -u fd -m 777 -o excl file)
Should be atomic. strace shows:
openat(AT_FDCWD, "file", O_RDONLY|O_CREAT|O_EXCL|O_NOCTTY, 0777) = 3
-o excl is for it to fail with a *»file exists»» error when the file already existed, so you can do (. ) || chmod 777 file for instance. Replace with -o creat to just open it (still in read-only with -r ) when it already existed. In any case, the fd is closed as soon as the subshell exists.
You can also set the uid and gid at the same time atomically if you’re superuser and set the EGID and EUID variables (in that order) beforehand:
(umask 0 && EGID=456 EUID=123 && sysopen -u fd -m 777 -o excl file)
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:
I don’t think you can really do this from just standard tools, but if you have access to a python interpreter, you can do something like:
python3 -c 'import os, sys, shutil; shutil.copyfileobj(sys.stdin, open("filename.txt", "w", opener=lambda name, flag: os.open(name, flag, mode=0o631)))'
Expanded, the python script basically does:
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)
There's probably something similar in other scripting language interpreter's toolkit.
$ 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)))' , 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 .
Alternatively, if the only reason you care about atomicity is just to prevent the file content being read from a hostile process running as other users, and not necessarily the use of atomicity of open(. mode) itself, you can just set the umask to 777 in a subprocess so that the file is first created to deny permission to everyone:
$ (umask 777; filename.txt) $ ls -lah filename.txt ---------- 1 lieryan lieryan 13 Sep 8 15:58 filename.txt
then set the file permission with the right value right afterwards:
Or, putting it all together:
$ (umask 777; filename.txt; chmod 631 filename.txt)
This is still susceptible to race condition attacks from other processes running as the same user, but if you have to worry about that, you're probably worrying about the wrong thing.
Forcing owner on created files and folders
I have a directory that contains data shared between a number of users. Access to this directory and anything underneath, will be controlled by the directory's group, which will be added to the users in question. As such I created the folder "sticky group" chmod g+s set. The directory will contain a tree structure with directories and files, with the total amount of files likely being a few million. The files will be fairly small, I don’t anticipate anything bigger than 50MB. My problem is that the owner of the file or directory is still the user that created it. As such, even if i should remove that user from the access group, I would not remove his access completely. So: Are there other options I missed for ensuring that all files and sub-directories have the same owner? I expect I could periodically surf through the entire directory with a cron-job, but that strikes me as inefficient for what is essentially a once-pr-file command. I found an example using INotify but that strikes me as high-maintenance, since it requires scripting. I haven't been able to figure out if ACL can help me with forced ownership. Is there a smarter way to do this? What I want is to have a directory that can be shared by adding a group to a user. Anything created in this directory inherits the permission scheme from its parent. If there is a better way than what I’m attempting, I’m all ears.
For setting all files and sub-directories having same group & ownership, why not to use chown -hR owner:group ?
It is possible, but since new files are being created all the time, and we are talking files in the millions, it would require a cron job that surfs the entire directory periodically. Unless i am missing some point?
File Operation with Linux Command
The second way of reading a file is using cat or more command.
Edit a file
- Edit the file's content.
- Save the file's changes with Ctrl + X then confirm by pressing Y . After that, hit Enter .
View files
To view a list of files can be done by using ls command.
To view a list of files with specific information. use ll command. This command outputs all files with specific information.
Here it is the information detail from ll command output.
-rw-r--r-- 1 nadir nadir 0 Jan 8 10:24 iamfile.txt access control number of link owner group size time created file name
To view a specific file information, use ll | grep filename command.
Move and Copy file
To move a certain file, use mv command followed with target file and target directory. In this example, the file called file.txt moved to the mydirectory directory.
To copy a certain file, use cp command followed with target file and target directory. In this example, the file called file_2.txt copied to the mydirectory directory.
Remove file and directory
To remove certain file, use rm command followed with file name. In this example, the file called file_2.txt will be removed.
To remove a directory, use rmdir command followed with directory name.
To remove a directory and its content. Use rm -rf .
Access Control in file
This access control also available for directory
There are three types of user in file's access control:
There are three types of file control:
- read: read or open the file ( r )
- write: write inside the file ( w )
- execute: execute a file ( x )
Access control mechanism can be done using chmod command followed with specific parameters to define the access control type. There are two ways to define the access control type.
1. Using characters
In this example, the file's access control defined using characters.
Based on the command above, the cool.txt file can be written, read and executed by user. The group and other user cannot write or edit the file, but available for read operation.
The complete formula of this command can be seen below:
chmod [user's type (u, g, o, a)] [-, +, =] [access type (r, w, x)]
Example, user only available for reading the file.
Another example, user only capable to read file, group available to write and other can read and write except execute the file:
2. Using numbers.
The number that used in file's access control is using binary number to define the access type of certain file. This is the sample usage.
Based on the command above, the user is available for all file's operation (read, write and execute), the group and the other user is only available to read the file.
The number 0 represents access is not available, when the number 1 represents access is available.
File ownership
To change the file or directory ownership, use chown command followed with user's name.
To change the file or directory ownership for group, use chgrp followed with group's name.
Tips
When you want to learn more about specific commands, just add --help after specific command.
I hope this article is helpful for learning about linux command especially for file operations. If you have any thoughts or feedbacks, you can write in the discussion section below.