I wish to hide files in Linux without using the dot, since it's possible in Windows.
Is there a way to do this?
Create a file .hidden
in the directory with the names of the files to be hidden (one name each line).
Then add the following to your ~/.bashrc
:
ls () {
if [ -f .hidden ]; then
declare GLOBIGNORE="$GLOBIGNORE:.*:$(tr '\n' ':' < .hidden)"
ls "$@"
fi
}
Now your ls
command does not list these files.
I use this technique to hide my __pycache__
and __init__.py
files.
EDIT: as per an other comment this also hides them in at least one (Nautilus), but probably several GUI file browsers as well.
ls -al
?
syntax error near unexpected token `('
. Adding function
to the beginning of the definition fixed this. But it looks like this definition doesn't play nicely with aliases: I kept on getting either SIGINT
s with ls --color=auto
or an infinite string of ls --color=auto --color=auto --color=auto ...
depending on where in my .bashrc I included it. If someone has a solution let me know. Ubuntu includes several aliases by default.
Jan 2, 2021 at 6:48
function
keyword was introduced in ksh. The traditional Bourne shell (bash) only had the foo ()
syntax, and POSIX standardizes only the foo ()
syntax.
You cannot. There is a fundamental difference in the way the file systems handle hidden settings. In Windows, the file system stores several attributes for the file in metadata, including the attributes "hidden" and "system" (both of which are kinds of hidden files). In common *nix filesystems, no such attribute is stored. Instead, the information must be put somewhere else, such as in the file name. The convention is thus that files beginning with . (and depending on your system, maybe some others like _) will not be shown by most tools by default.
This is purely for convenience, a . beginning a file name means absolutely nothing but "the user probably doesn't want to see this all the time." To make sure that you know, running e.g. ls -a
will show all files.
If you don't want to have a file clutter up your listings in Linux, you should rename it to start with a dot (Bonus: this will work for OS X too, if we're talking about a portable device). If you don't want users to be able to find a file, you're doing it wrong - that's what permissions are for.
Unix permissions as they pertain to directories often confuse people, and maybe understanding it better will help you. The "read" and "execute" permissions (r
and x
) mean something different for directories than they do for files. For directories, the execute x
permission determines whether or not you access the inodes in the directory. The read r
permission dictates whether or not you can access the listing of the directory. Functionally, x
allows the user to do things in a directory, while the r
permission allows them to see what's in it. These are different, and the difference can be confusing. Let's look at an example:
jeanluc@login64: ~ $ mkdir example
jeanluc@login64: ~ $ echo "you can read it" > example/file
jeanluc@login64: ~ $ ls example/
file
jeanluc@login64: ~ $ cat example/file
you can read it
jeanluc@login64: ~ $ chmod -x example/
jeanluc@login64: ~ $ ls example/
ls: cannot access example/file: Permission denied
file
jeanluc@login64: ~ $ cat example/file
cat: example/file: Permission denied
jeanluc@login64: ~ $ cd example/
-bash: cd: example/: Permission denied
jeanluc@login64: ~ $ chmod +x example/
jeanluc@login64: ~ $ chmod -r example/
jeanluc@login64: ~ $ ls example/
ls: cannot open directory example/: Permission denied
jeanluc@login64: ~ $ cat example/file
you can read it
jeanluc@login64: ~ $ cd example/
jeanluc@login64: ~/example $ ls
ls: cannot open directory .: Permission denied
jeanluc@login64: ~/example $ cd ..
So, notice that without execute I can still list the files (although ls shows an error because it cannot get the file properties), but I can't change in to the directory or read the files in it. Without read I cannot list the files, but I can still change in to the directory and if I know the name of a file I can still access it.
Do note, though, that removing the read permission only gives you security by obscurity. If the user guesses the file name, they will be able to read its contents.
This may not have really been relevant to your question, I just wanted to make sure you understood directory permissions.
You can actually hide files in Linux without adding a dot. This actually hides them in Nautilus; an ls
from the command line will still list the files.
.hidden
in the folder where you want to hide the files.A dot is used to hide files in linux, and that can not be changed.
However, you could play with the file permissions to prevent users from being able to have access to given folder/file. Try experimenting with chmod
command.
If you have some programming skills and if only what you need is hidding filenames for user convinience to stop cluttering the visual space you can hack it!
I will consider command line tools only, as they are quite uniform and are the only tools constantly used be me.
There many ways to store this information:
You can store "hidden" extended attribute in selected files. See man attr
attr -s hidden -V true your_file
Or as mentioned above you can store list of filename in .hidden
file
Important: This will not work out of the box you have to implement the logic, clean systems will just ignore .hidden
files and hidden
extended attributes!
Also there are muliple possible implementations:
If you have only few files, write in your .bashrc
file
alias ls='ls -I filename_1 -I filename_2'
man ls
for more information.
Write a function ls
such as it handles all the logic behind recognizing
hidden files and assembling list of all -I
entries, and then executing
/bin/ls
with proper ignore flags. Very laborious task, because you have
to handle all ls
parameters properly.
Get sources of coreutils
git clone git://git.sv.gnu.org/coreutils
or
git clone git://git.suckless.org/sbase
Patch it the way you need to handle your implementation of hidden files.
And place it in your PATH
I hacked it in less then 5 minutes using suckless sources and diff is like this:
diff --git a/ls.c b/ls.c
index cdfce4d..8197409 100644
--- a/ls.c
+++ b/ls.c
@@ -214,6 +214,17 @@ lsdir(const char *path)
first = 0;
while ((d = readdir(dp))) {
+///////////////////////////////////////////////
+// Dirty hack to implement hidden files
+// FIXME: Make proper(!) subroutine
+ char attr_command[1024] = "attr -Lqg hidden "; // Oh, dear. That's bad
+ int attr_code;
+ strcat(attr_command, d->d_name);
+ strcat(attr_command, " >/dev/null 2>&1");
+ attr_code = system(attr_command);
+ if (!attr_code)
+ continue;
+///////////////////////////////////////////////
if (d->d_name[0] == '.' && !aflag && !Aflag)
continue;
else if (Aflag)
ls.c
lies in src
, not the root directory, and there is no function lsdir
in ls.c
.
Are you only trying to hide files from your graphical user interface's file manager and/or desktop environment? If so, there might be options beyond simply prefixing the filename with a dot.
I believe the only additional files hidden by any Linux file manager are backup files, i.e. those ending in a tilde ~
or .bak
or whatever they believe is the backup extension. In any case, you are probably in luck if all you wish to do is hide backup files from the file manager.
Do not give your files a backup extension to hide them or they might get accidentally deleted!!
As an aside, you can hide files from the Finder in Mac OS X using the command SetFile -a V [file]
or editing /.hidden
but obviously this won't hide the file from the command line's ls
program.
This is the best solution I have found, add to your profile:
alias ls="/bin/ls --color=auto --ignore='*.egg-info' --ignore='__pycache__'"
If you need more patterns just add more --ignore
flags.
Nowadays you can write FUSE that hides files according to given config.
This article makes me believe you need to tweak the getdir
function:
getdir: int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
This reads the contents of a directory. This operation is theopendir()
,readdir()
, …,closedir()
sequence in one call. For each directory entry, thefilldir()
function should be called.
I'm not a programmer but I imagine one could make getdir
omit all files listed in (e.g.) .hidden
file. If you implement this correctly then every tool (GUI or not) will be affected.
You can 'hide' the contents of a directory by taking away 'x' perms for the group, or other: chmod go-x directoryname
. You could no longer list files, though you could access a file if you knew the exact path. This does not sound like what you want.
Keep in mind the dotfile thing is a convenience, not really to hide the file for security sake, but to reduce clutter for files during file listing. It's baked into ls
and the other tools.
Add this to your .bashrc and your files won't be visible with ls command
function ls () {
command ls "$@" -I fileA -I fileB
}