How to write protect a file in macOS
Social Share:
Saturday, July 6, 2024 at 10:36 AM | 6 min read
Last modified on Monday, September 21, 2026 at 2:36 PM
#chflags, #command line, #macOS, #modify file flags, #schg, #shell scripting, #system immutable flag, #uchg, #user immutable flag, #write protect files

Photo by Mr Cup / Fabien Barral on unsplash.com
Table of Contents
- Write protecting files with chflags schg
- Un-write protecting files with chflags noschg
- Write protecting files with chflags uchg
- Un-write protecting files with chflags nouchg
- Write protecting folders with chflags -R schg
- Un-write protecting folders with chflags -R noschg
- Write protecting folders with chflags -R uchg
- Un-write protecting folders with chflags -R nouchg
- Conclusion
- Related Resources
I wrote this post for those of us who have regrettably deleted files and folders, never to see them again. This post discusses how to write protect those files and folders.
Write protecting files with chflags schg
Sometimes you want to make sure that important files are not removed via command line when using the rm (remove) or rm -rf (remove + -r for recursive and -f for force) commands. You want to make sure that these important files are write protected from such commands.
I'm going to use one of my shell script files I keep for demonstrations such as these. In general, I want to make sure that my shell scripts cannot accidentally be removed either!
When a file is "write protected", that means that it is "unalterable". It cannot be changed or deleted by any type of user, including root (or superuser) in the macOS UNIX operating system. And only root or a user with sudo privileges can clear the schg flag.
First I use the chflags (change flags) command followed by the schg (set the system immutable flag) flag. This sets the "system immutable flag" type on a file:
chflags schg hello.sh
However, if I run the above command as is, the Terminal prints:
chflags: hello.sh: Operation not permitted
That's because I have to run it as superuser. So I have to add sudo to the beginning of the command like so:
sudo chflags schg hello.sh
And the Terminal prompts:
Password:
I have to input my user password.
Then, if I try to delete the hello.sh script file with the command rm hello.sh, the Terminal displays:
override rwx------ mariacam/staff schg for hello.sh?
If I run the ls -lO hello.sh (lowercase L and uppercase O) command, it returns:
-rwx------@ 1 mariacam staff schg 44 Jul 5 2024 hello.sh
schg appears to the right of staff, indicating that it is a schg write protected file.
Un-write protecting files with chflags noschg
To clear the schg flag so I can go back to being able to manipulate my file(s) again, I run:
sudo chflags noschg hello.sh
Then I run ls -lO hello.sh and get back:
-rwx------@ 1 mariacam staff - 44 Jul 5 2024 hello.sh
Now the schg flag is gone and I can manipulate hello.sh however I want. If I want to change the name of the file, for instance, I can:
~/macos-scripting mv hello.sh hi.sh ~/macos-scripting ls -file paste.txt banana.txt paste2.txt concatenate.sh peanutes.txt concatenate.txt peanuts.txt cut.txt play_album.sh download_install_firefox.sh play_song.sh file1.txt result.txt file1a.txt set-browser.sh file2.txt show_hidden_files.sh hi.sh some-file.txt hide_hidden_files.sh test.txt list-directory.txt wifi_reset.sh myoutput.txt
This is proof that the sudo chflags noschg hello.sh command to remove the schg flag worked. And, if I want to change back hi.sh to hello.sh, I can:
~/macos-scripting mv hi.sh hello.sh
And then:
~/macos-scripting ls -file paste.txt banana.txt paste2.txt concatenate.sh peanutes.txt concatenate.txt peanuts.txt cut.txt play_album.sh download_install_firefox.sh play_song.sh file1.txt result.txt file1a.txt set-browser.sh file2.txt show_hidden_files.sh hello.sh some-file.txt hide_hidden_files.sh test.txt list-directory.txt wifi_reset.sh myoutput.txt
I am able to successfully change the name of the hi.sh file back to hello.sh because I first remove the schg flag from it.
Write protecting files with chflags uchg
I can also run the following command without sudo:
chflags uchg hello.sh
uchg represents the "user immutable flag". With the "system immutable flag" (schg), the superuser can remove whichever schg chflags flag is present, no matter who owns which file. With the "user immutable flag" (uchg), only the owner can delete protected files which they own only after removing the uchg chflags flag. Other users on the system cannot remove another owner/user's uchg flags. Only the superuser can.
So if I run the chflags uchg hello.sh command, followed by the rm hello.sh command, I get:
override rwx------ mariacam/staff uchg for hello.sh?
I can either type "y" for "yes" if I want to actually delete the file, or "n" for "no" if I don't. This prompt gives me the opportunity to change my mind before actually deleting the file. However, if I do type "y" to remove the file, I get back:
rm: hello.sh: Operation not permitted
This proves that the hello.sh file is truly "write protected" or "immutable".
Un-write protecting files with chflags nouchg
If I decide that I no longer want the hello.sh file to be write protected, I can "unprotect" the file and therefore delete it with the rm command. To achieve this, I run:
chflags nouchg hello.sh
And then if I run the following command:
ls -lO hello.sh
Terminal shows:
-rwx------@ 1 mariacam staff - 44 Jul 5 2024 hello.sh
And then if I run rm hello.sh followed by the ls command inside the macos-scripting folder where hello.sh resided, Terminal yields:
~/macos-scripting ls -file paste.txt banana.txt paste2.txt concatenate.sh peanutes.txt concatenate.txt peanuts.txt cut.txt play_album.sh download_install_firefox.sh play_song.sh file1.txt result.txt file1a.txt set-browser.sh file2.txt show_hidden_files.sh hide_hidden_files.sh some-file.txt list-directory.txt test.txt myoutput.txt wifi_reset.sh
The hello.sh file is successfully removed.
Write protecting folders with chflags -R schg
The chflags command (and uchg flag) is not limited to files. It can be used on folders as well.
I can create a directory called chflags-demo-folder, and inside it I can add the following subfolders and files:
~/chflags-demo-folder ls chflags-schg-two.txt schg-folder chflags-schg.txt schg-folder-two
Then I run sudo chflags -R schg chflags-demo-folder followed by ls -ldO chflags-demo-folder to make sure that the command took:
# ls -ldO chflags-demo-folder displays the parent directory settings drwxr-xr-x 6 mariacam staff schg 192 Sep 20 20:20 chflags-demo-folder
It took! Next, I want to make sure that the directory contents were affected as well:
# this command displays the contents of the parent directory ls -lO chflags-demo-folder total 0 -rw-r--r-- 1 mariacam staff schg 0 Sep 20 20:01 chflags-schg-two.txt -rw-r--r-- 1 mariacam staff schg 0 Sep 20 20:01 chflags-schg.txt drwxr-xr-x 4 mariacam staff schg 128 Sep 20 20:21 schg-folder drwxr-xr-x 4 mariacam staff schg 128 Sep 20 20:21 schg-folder-two
chflags -R schg write protects all the directory's subfolders and files.
But I want to make sure that the subfolders' files have also been protected:
~ cd chflags-demo-folder ~/chflags-demo-folder ls chflags-schg-two.txt schg-folder chflags-schg.txt schg-folder-two ~/chflags-demo-folder cd schg-folder ~/chflags-demo-folder/schg-folder ls test-file-one.txt test-file-two.txt ~/chflags-demo-folder/schg-folder ls -lO total 0 -rw-r--r-- 1 mariacam staff schg 0 Sep 20 20:20 test-file-one.txt -rw-r--r-- 1 mariacam staff schg 0 Sep 20 20:21 test-file-two.txt
Not only does the command protect the parent directory's subfolders and files, but it also protects the subfolders' files.
But I also want to make sure that this folder and its contents are protected from potentially dangerous commands such as (previously mentioned) rm -rf.
When I run rm -rf chflags-demo-folder, it results in:
~ rm -rf chflags-demo-folder rm: chflags-demo-folder/schg-folder-two/test-file-three.txt: Operation not permitted rm: chflags-demo-folder/schg-folder-two/test-file-four.txt: Operation not permitted rm: chflags-demo-folder/schg-folder-two: Operation not permitted rm: chflags-demo-folder/chflags-schg.txt: Operation not permitted rm: chflags-demo-folder/chflags-schg-two.txt: Operation not permitted rm: chflags-demo-folder/schg-folder/test-file-two.txt: Operation not permitted rm: chflags-demo-folder/schg-folder/test-file-one.txt: Operation not permitted rm: chflags-demo-folder/schg-folder: Operation not permitted rm: chflags-demo-folder: Operation not permitted
chflags -R schg provides robust protection against the rm -rf command while the schg flag is set.
Un-write protecting folders with chflags -R noschg
Un-write protecting folders and all their contents is similar to un-write protecting files. To un-write protect chflags-demo-folder, I run:
sudo chflags -R noschg chflags-demo-folder
And then:
# -l flag stands for long format. It lists permissions, owner, # size, and date. # -d shows a directory itself, as if it were a plain file, # instead of listing what's inside it. # -O includes the file flags in the long listing. # This is the option that shows schg or uchg, # and it's a capital letter O. ~ ls -ldO chflags-demo-folder drwxr-xr-x 6 mariacam staff - 192 Sep 20 20:20 chflags-demo-folder
The command clears all protection from the parent directory and its contents. Running ls -lO chflags-demo-folder and then ls -lO schg-folder and ls -lO schg-folder-two confirms it:
~ ls -lO chflags-demo-folder total 0 -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:01 chflags-schg-two.txt -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:01 chflags-schg.txt drwxr-xr-x 4 mariacam staff - 128 Sep 20 20:21 schg-folder drwxr-xr-x 4 mariacam staff - 128 Sep 20 20:21 schg-folder-two ~/chflags-demo-folder ls -lO schg-folder total 0 -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:20 test-file-one.txt -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:21 test-file-two.txt ~/chflags-demo-folder ls -lO schg-folder-two total 0 -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:21 test-file-four.txt -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:21 test-file-three.txt
Write protecting folders with chflags -R uchg
To write protect a folder using the uchg flag, I use the following command:
~ chflags -R uchg chflags-demo-folder # Then: ~ ls -lO chflags-demo-folder total 0 -rw-r--r-- 1 mariacam staff uchg 0 Sep 20 20:01 chflags-schg-two.txt -rw-r--r-- 1 mariacam staff uchg 0 Sep 20 20:01 chflags-schg.txt drwxr-xr-x 4 mariacam staff uchg 128 Sep 20 20:21 schg-folder drwxr-xr-x 4 mariacam staff uchg 128 Sep 20 20:21 schg-folder-two
Un-write protecting folders with chflags -R nouchg
To un-write protect the chflags-demo-folder, I use:
~ chflags -R nouchg chflags-demo-folder
Followed by:
ls -lO chflags-demo-folder # Which results in: total 0 -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:01 chflags-schg-two.txt -rw-r--r-- 1 mariacam staff - 0 Sep 20 20:01 chflags-schg.txt drwxr-xr-x 4 mariacam staff - 128 Sep 20 20:21 schg-folder drwxr-xr-x 4 mariacam staff - 128 Sep 20 20:21 schg-folder-two
Conclusion
In this post, I demonstrate how to write protect files and folders in UNIX/macOS. I discuss how only a superuser or a user with sudo (which stands for "superuser do") privileges can set the schg (System Immutable) chflags flag on a file or folder. On the other hand, users can use the uchg (user immutable) chflags flag without sudo on files or folders, and only the owner of the protected file (or the superuser) can remove that flag. The same principles apply to folders. So if you have important and/or sensitive files or folders that you cannot afford to lose, the chflags command and related flags are for you!
Related Resources
-
Apple OS X: Write Protect File From Command Line: by Vivek Gite, cyberciti.biz
-
chflags man page: Xcode man pages on GitHub