March 10, 2020•2,592 words
<b>chattr</b> [<b>-R</b>] [<b>-V</b>] [<b>-f</b>] [<b>-v</b> <i>version</i>] [<b>-p</b> <i>project</i>] <i>mode</i> ... <i>file</i> ...
chattr takes the following options:
|-R||Recursively change attributes of directories and their contents.|
|-V||Provide verbose output and display program version.|
|-f||Suppress most error messages.|
|-v version||Set the file's version/generation number. This is an arbitrary nine-digit number assigned to a file when it is created. It is not unique. It may be changed to any other arbitrary number.|
|-p project||Set the file's project number.|
|mode ...||One or more mode strings. For more information, see Mode strings, below.|
|file ...||The file or files to be changed.|
A mode string consists of an operator and one or more attributes. It takes the form:
One of the following operators must appear at the beginning of a mode string:
|+||Attributes listed will be added to the file.|
|-||Attributes listed will be removed from the file.|
|=||The attributes listed will be added; any attributes omitted will be removed.|
The remainder of the mode string is a series of characters, each representing an attribute. They are case-sensitive, cannot be separated by whitespace, and may appear in any order. For a list of attribute characters, see Attributes, below.
Example mode strings are "+caS", "-Asd", and "=eAsS".
Multiple mode strings may be specified to combine + and - operators in a single command, e.g. "+asD -c" and "-a +s +D -c" are both valid.
<b>lsattr</b> [<b>-R</b>] [<b>-V</b>] [<b>-a</b>] [<b>-d</b>] [<b>-v</b>] <i>file</i> ...
|-R||Recursively list attributes of directories and their contents.|
|-V||Display the program version.|
|-a||List all files in a directory, including those whose name starts with a period ('.').|
|-d||List directories as regular files, rather than listing their contents.|
|-v||List the file's version/generation number in addition to its attributes.|
List of Attributes
The following characters represent attributes that may be modified by chattr or listed with lsattr.
|a||append only||The file may only be opened for writing in append mode: its existing data may not be overwritten. It cannot be deleted or renamed; hard links cannot be made to this file; most of its metadata cannot be changed. Modifying this attribute requires root privileges.|
|A||no atime updates||When the file is accessed, its atime record is not modified, which in some situations can reduce disk I/O.|
|c||compressed||Files with this attribute are automatically compressed by the kernel when written to disk. Its contents are uncompressed when read. Note: This attribute has no effect in the ext2, ext3, and ext4 filesystems.|
|C||no copy on write||Files with this attribute are not subject to copy-on-write updates. If this attribute is set on a directory, new files created in that directory will have this attribute set. Note: This attribute is only effective on filesystems which perform copy-on-write. On btrfs, this attribute should be set on new or empty files. If this attribute is set after a btrfs file already contains data, the time when its data will be stable is undefined.|
|d||no dump||Files with this attribute are bypassed in any backup initiated by dump, a legacy tool for ext2 filesystems.|
|D||synchronous directory updates||Changes to a directory with this attribute are written synchronously to disk. That is, the system waits for write completion before doing something else. Equivalent to the the dirsync option to the mount command, applied to a subset of files on a filesystem.|
|e||block extents||Indicates that a file should be stored using block extents. Data is stored contiguously between two blocks, and only those two blocks must be known to find the file's data. Block extent mapping may potentially save disk space, because it reduces the number of blocks which must be listed in the file's inode.|
|i||immutable||Files with this attribute cannot be deleted or renamed; hard links cannot be made to this file; most of its metadata cannot be changed; data cannot be written to the file. Modifying this attribute requires root, or a process with the CAP_LINUX_IMMUTABLE capability, as set with setcap.|
|j||data journalling||A file with this attribute has all its data written to its journal before being written to the file itself. Only effective on ext3 and ext4 filesystems which have journalling enabled and the "data=ordered" or "data=writeback" options set. If journaling is enabled in those systems, but the "data=journal" option is set, this attribute has no effect. Only root or a process with CAP_SYS_RESOURCE capability as set with setcap can change this attribute.|
|P||project hierarchy||A directory with this attribute will enforce a hierarchical structure for project IDs. Files and directories created in the directory will inherit the project ID of the directory. Rename operations are constrained so when those files or directories are moved to another directory, the project IDs will match. Hard links to these files may only be created if the project ID of the target and destination match.|
|s||secure deletion||If a file with this attribute is deleted, its data is overwritten with zeroes, similar to a simple shred. This attribute is ignored by ext2, ext3, and ext4 filesystems.|
|S||synchronous updates||When files with this attribute are modified, the changes are written synchronously to disk. Equivalent to the sync option of the mount command, for individual files.|
|t||no tail merging||A file with this attribute will not have any partial block fragment at the end of the file shared with another file's data. This attribute is necessary for software such as LILO, which reads the filesystem directly and is not aware of tail merging. Some filesystems do not support tail merging, in which case this attribute has no effect.|
|T||top of directory hierarchy||A directory with this attribute is deemed to be the top of directory hierarchies by the Orlov block allocator, used by ext2 and ext3. The attribute gives a hint to the allocator that the subdirectories are not related in how they are used, and their data should be separate when blocks are allocated. For example, the /home directory may have this attribute, indicating that /home/mary and /home/john should be placed in separate block groups.|
|u||undeletable||When a file with this attribute is deleted, its contents are saved, enabling their later undeletion. Undelete tools which can take advantage of this attribute include extundelete.|
The following attributes are read-only. They cannot be set or unset by chattr, but can be listed by lsattr.
|E||compression error||The filesystem is not able to automatically compress this file.|
|h||huge file||The file is storing its blocks in units of the filesystem's blocksize instead of in sectors. The file is, or previously was, larger than 2 TB.|
|I||indexed directory||The directory is being indexed with a hashed tree (htree).|
|N||inline data||The file has data stored inline, within the inode itself.|
|X||compression raw access||An experimental attribute indicating that the raw contents of a compressed file may be accessed directly.|
|Z||compressed dirty file||An experimental attribute indicating that a compressed file is dirty (incompletely written).|
View attributes of files
For this example, we will create three empty files with touch:
touch file file2 .file
We can view their permissions with ls, using the -l option:
total 8 -rw-rw-r-- 1 hope hope 0 Jun 28 09:51 file -rw-rw-r-- 1 hope hope 0 Jun 28 09:51 file2
File names starting with a dot (period) are not listed by ls unless the -a option is used:
total 28 -rw-rw-r-- 1 hope hope 0 Jun 28 09:51 file -rw-rw-r-- 1 hope hope 0 Jun 28 09:51 .file -rw-rw-r-- 1 hope hope 0 Jun 28 09:51 file2
Now let's view attributes by running lsattr:
-------------e-- ./file -------------e-- ./file2
As with ls, we must use the -a option to view files whose name starts with a dot:
-------------e-- ./file -------------e-- ./file2 -------------e-- ./.file -------------e-- ./. -------------e-- ./..
To view the attributes of a specific file or files, specify their names:
lsattr -a file file2 .file
-------------e-- file -------------e-- file2 -------------e-- .file
View attributes of directories
Now let's create a directory and subdirectory with mkdir -p:
mkdir -p dir/subdir
And create some empty files in those directories:
touch dir/file3 dir/file4 dir/subdir/file5
By default, lsattr does not traverse directories:
-------------e-- ./file -------------e-- ./file2 -------------e-- ./dir
To recursively traverse and show the contents of directories, use -R:
-------------e-- ./file -------------e-- ./file2 -------------e-- ./dir ./dir: -------------e-- ./dir/file3 -------------e-- ./dir/file4 -------------e-- ./dir/subdir ./dir/subdir: -------------e-- ./dir/subdir/file5
By default, the files and directories we created in the above examples (on Ubuntu 16.04) have the "block extents" attribute (e) set.
-------------e-- ./file -------------e-- ./file2 -------------e-- ./dir
Let's give them the d attribute (a legacy attribute, meaningless on our system), using +d.
chattr +d *
------d------e-- ./file ------d------e-- ./file2 ------d------e-- ./dir
Some attributes, such as a (append-only), may only be modified by the root user:
<a href="https://www.computerhope.com/unix/sudo.htm">sudo</a> chattr +a file
-----ad------e-- ./file ------d------e-- ./file2 ------d------e-- ./dir
Attributes which apply only to directories, such as D, will not be set on regular files, successfully — no error will be returned. For example, if you try to run chattr +D on a regular file, chattr will do nothing to those files, and return a successful exit status.
Notice in the next command that we try to set the D attribute on both a regular file and a directory. The attribute is set on the directory, is not set on the regular file, and chattr returns successfully.
chattr +D file dir && lsattr
-----ad------e-- ./file ------d------e-- ./file2 ---D--d------e-- ./dir
(The && control operator will run the next command only if the previous command returns a successful exit status. For more information, see Shell grammar in bash.)
To unset an attribute, use the - operator before your list of attributes.
chattr -D dir && lsattr
-----ad------e-- ./file -------------e-- ./file2 -------------e-- ./dir
Only one operator may be specified per mode string, but you can specify multiple attributes one after the other (without whitespace), in any order. You may specify multiple mode strings, each with their own operator.
chattr +sSc -d * && lsattr
s-S--a--c-----e---- ./file s-S-----c-----e---- ./file2 s-S-----c-----e---- ./dir
If an attribute requires root privileges, but you are not running the command as root, chattr will not change any attributes for that file. It will continue trying to operate on other files, and when it completes, it will return a failing exit status (an error).
To illustrate this, in the next command, we'll try to set the a attribute on every file in the current directory without using sudo. This should fail (unless we are logged in as root), because setting a requires superuser privileges.
Also, note that in the next command we use echo to display the value of the bash special parameter ? (a question mark). The ? parameter contains the exit status of the previous command, so it will tell us if chattr succeeded (0) or failed (1). Like all bash parameters, we refer to its value by prefixing its name with $.
chattr -sS +a *; echo $?
chattr: Operation not permitted while setting flags on dir chattr: Operation not permitted while setting flags on file2 1
The exit status 1 indicates an error occurred.
Let's look at how the attributes changed:
-----a--c-----e---- ./file s-S-----c-----e---- ./file2 s-S-----c-----e---- ./dir
Notice that file did not cause an error. It already had the a flag from a previous command, so it causes no error; and so the rest of the changes (-sS) went through just fine. The other file and directory both caused an error, and were entirely unchanged.
To set every file to match an explicit set of attributes, use the = operator. Any listed attributes will be set, and any not listed will be unset.
sudo chattr -R =es * && lsattr -R
s----------e---- ./file s----------e---- ./file2 s----------e---- ./dir ./dir: s----------e---- ./dir/file3 s----------e---- ./dir/file4 s----------e---- ./dir/subdir ./dir/subdir: s----------e---- ./dir/subdir/file5
Make files immutable
If you set the i attribute, a file will be marked as "immutable", meaning its data (and some vital metadata) cannot be changed, even by root, until the attribute is unset.
touch immutable && lsattr immutable
sudo chattr +i immutable && lsattr immutable
<a href="https://www.computerhope.com/unix/umv.htm">mv</a> immutable newname
mv: cannot move 'immutable' to 'newname': Operation not permitted
<a href="https://www.computerhope.com/unix/urm.htm">rm</a> immutable
rm: cannot remove 'immutable': Operation not permitted
sudo rm -f immutable
rm: cannot remove 'immutable': Operation not permitted
You cannot create a hard link to an immutable file:
<a href="https://www.computerhope.com/unix/uln.htm">ln</a> immutable hardlink
ln: failed to create hard link 'hardlink' => 'immutable': Operation not permitted
Symbolic links are OK, though:
ln -s immutable symlink && ls -l symlink
lrwxrwxrwx 1 hope hope 6 Jun 29 07:49 symlink -> immutable
This is a good time to note that symbolic links have no attributes of their own:
lsattr: Operation not supported While reading flags on symlink
To make files mutable again, use -i:
sudo chattr -i immutable && mv immutable newname && lsattr newname
Make files append-only
The append-only attribute (a) makes a file immutable, except that data can be added to it.
touch appendonly && lsattr appendonly
sudo chattr +a appendonly && lsattr appendonly
You cannot overwrite the file with redirection (>):
echo "Overwriting is not allowed." > appendonly
bash: appendonly: Operation not permitted
But redirecting append-only (>>) is OK:
echo "Appending is allowed." >> appendonly && <a href="https://www.computerhope.com/unix/ucat.htm">cat</a> appendonly
Appending is allowed.
echo "Appending is allowed." >> appendonly && cat appendonly
Appending is allowed. Appending is allowed.
Append-only files may not be moved, removed, renamed, or hard-linked.
sudo rm -f appendonly
rm: cannot remove 'appendonly': Operation not permitted
sudo ln appendonly hardlink
ln: failed to create hard link 'hardlink' => 'appendonly': Operation not permitted
For more information about redirection, see Redirection in bash.