Single command to create a file and set its permission

ShellUnixFile PermissionsKsh

Shell Problem Overview


I am using the following 2 commands to create a 0B file and set its extn to 644

touch filename.ext
chmod 777 filename.txt

My question is that whether there is any single command in unix (korn shell) that will do the two things together that is to say create a 0B fil with desired permission?

Shell Solutions


Solution 1 - Shell

install -m 777 /dev/null filename.txt

Solution 2 - Shell

For bash, simply use chmod with file redirection and history expansion:

chmod 777 filename.txt>>!#:2

For ksh and zsh you have to drop the history expansion (as shown above, there may be other ways) and use:

chmod 644 filename>>filename

For scripts of any shell you don't have (and really don't need) history expansion so use the above there as well.

Solution 3 - Shell

First of all, you should NEVER be setting anything to 777 permissions. This is a huge security problem and there just isn't any need for it. For the purposes of this question I will assume you want to create a file with more secure permissions than the defaults, say 600.

There is not a one stop way to safely create AND change the permissions of a file using most bash tools. Even the tricky redirection trick in Paul's answer actually momentarily creates a file with default permissions before resetting them. All new files get created with whatever the system umask value is set too unless the creating program sends very specific requests to the operating system at the time of node creation. A mask of 133 is common, meaning your files get created with 644 permissions out of the box.

Besides using the chmod command to set the file permissions after you create a file, you can also tell the system what defaults you want using the umask command.

$ umask 077
$ touch test_file
$ ls -l test_file
-rw------- 1 user group 0 Jan 24 22:43 test_file

You will note the file has been created with 600 permissions.

This will stay in effect for all commands run in a shell until you either close that shell or manually set another value. If you would like to use this construct to run a single command (or even a small set of them) it can be useful to isolate the commands in a subshell

$ (umask 077 ; touch test_file)

Note that anything else you put inside the parens will use that umask but as soon as you close it, you are back in your previous environment.

Solution 4 - Shell

If you want to create the file not just empty but with content and mode at the same time you can use process substitution with install in bash:

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

<() places the output into a temporary file (Process-Substitution)

Solution 5 - Shell

You can create your own command:

create () {
    touch "$1"
    chmod "$2" "$1"
}

create filename.ext 644

Solution 6 - Shell

The only reason your files are not created with 666 permissions right off of the bat is the umask. So if you disable the umask:

umask 0

then when you touch the file it will end up with permissions 666 automatically. It would not be a good idea to make text files executable usually. Directories would end up with 777 permission with umask disabled.

chicks@freecandy /tmp $ umask
0022
chicks@freecandy /tmp $ touch x
chicks@freecandy /tmp $ mkdir xx

chicks@freecandy /tmp $ umask 0
chicks@freecandy /tmp $ touch y
chicks@freecandy /tmp $ mkdir yy

chicks@freecandy /tmp $ ls -ld x xx y yy                                                                                  
-rw-r--r-- 1 chicks chicks  484 Jan 24 14:37 x
drwxr-xr-x 2 chicks chicks 4096 Jan 24 14:37 xx
-rw-rw-rw- 1 chicks chicks    0 Jan 24 14:37 y
drwxrwxrwx 2 chicks chicks 4096 Jan 24 14:37 yy

Solution 7 - Shell

touch filename.ext && chmod 777 $_

$_ is the most recent parameter

but as others have said 777 isn't a good idea

Solution 8 - Shell

Applying this to Docker

Because of Docker and Alpine, I imagine there are a lot of people interested in creating executable one-liners without the help of bash-isms. It's pretty simple with install

$ docker build -t temp - <<EOF
FROM alpine
RUN echo "date" | install -m 775 /dev/stdin /bin/now
CMD /bin/now
EOF

Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine
 ---> d6e46aa2470d
Step 2/3 : RUN echo "date" | install -m 775 /dev/stdin /bin/now
 ---> Running in 95919b575638
Removing intermediate container 95919b575638
 ---> cd1fafd96ef3
Step 3/3 : CMD /bin/now
 ---> Running in 03b5c3ac7265
Removing intermediate container 03b5c3ac7265
 ---> 8f30b527dd29
Successfully built 8f30b527dd29
Successfully tagged temp:latest

$ docker run --rm temp
Thu Nov 12 07:44:24 UTC 2020

$ docker run --rm temp ls -la /bin/now
-rwxrwxr-x    1 root     root             5 Nov 12 07:44 /bin/now

$ docker rmi temp
Untagged: temp:latest
Deleted: sha256:8f30b527dd29203b67c86290b34b0a29d3c98a48134609d0b1e2b89087a7d6e7
Deleted: sha256:cd1fafd96ef3084226c5f98f472e3e08bc9a9f0448cc3e68b6f1c192d12d778a
Deleted: sha256:e58c75acbf953a64d35089cf50e1c5b762601e1cb9d9d1d668e135f23ce1fe86

Update

A commenter said:

> I don't get what this has to do with the question.

  1. The OP's subject for this Q was "Single command to create a file and set its permission"
  2. The OP included "single command in unix (korn shell) that will do the two things together"

The subject causes this Q to come up for Docker users' Google searches. The OP specified "korn shell" which implies avoiding bash specific features. Because Alpine and many other minimal Linux bases used in containers does not include bash, the top ranked answer is not going to work for them. My answer does work for them and the OP's korn shell. Using Docker to demonstrate a solution means that anyone using Linux, macOS, Windows, or WSL2 in Windows can easily recreate the demo on their machine by reading the transcript from my machine.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3075776View Question on Stackoverflow
Solution 1 - ShellproskiView Answer on Stackoverflow
Solution 2 - ShellPaul EvansView Answer on Stackoverflow
Solution 3 - ShellCalebView Answer on Stackoverflow
Solution 4 - ShelllaktakView Answer on Stackoverflow
Solution 5 - ShellRoberto BonvalletView Answer on Stackoverflow
Solution 6 - ShellchicksView Answer on Stackoverflow
Solution 7 - ShellSDTboneView Answer on Stackoverflow
Solution 8 - ShellBruno BronoskyView Answer on Stackoverflow