How to write protect a file in macOS

    Saturday, July 6, 2024 at 10:36 AM | 6 min read

    Last modified on Monday, September 21, 2026 at 2:36 PM

    , , , , , , , , ,

    Vinyl collection at a record store

    Photo by Mr Cup / Fabien Barral on unsplash.com

    Table of Contents

    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!

    loading