38

I wish to hide files in Linux without using the dot, since it's possible in Windows.

Is there a way to do this?

1
  • 7
    Keep in mind hiding files (obfuscation) is not replacement for security (restricting access)
    – uSlackr
    Nov 21, 2011 at 15:32

10 Answers 10

31

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.

4
  • it is interesting. Does it work also in the nautilus or other gui tools? Are you able to see the files with ls -al?
    – Jakuje
    Dec 27, 2015 at 19:22
  • 1
    code is missing a ' " at the end. (and in case you wonder where the upvotes are from: askubuntu.com/a/713591/15811 ) ;-)
    – Rinzwind
    Dec 28, 2015 at 14:14
  • 1
    I got a syntax error 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 SIGINTs 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
  • The function keyword was introduced in ksh. The traditional Bourne shell (bash) only had the foo () syntax, and POSIX standardizes only the foo () syntax.
    – A Sz
    Jan 14, 2021 at 10:01
27

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.

15

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.

  1. Create a text file named .hidden in the folder where you want to hide the files.
  2. Add the names of the files or folders you want to hide, one per line, to the file.
  3. Refresh your file browser.
4
  • 2
    does not work here with "ls" in debian 5.0. Is it specific to nautilus or dolphin or ...? Feb 4, 2013 at 20:40
  • 2
    Files are hidden in Nautilus; not in ls lists.
    – To Do
    Feb 4, 2013 at 21:03
  • 1
    just awesome solution! :)
    – KodeFor.Me
    Dec 9, 2017 at 8:42
  • +1 Worked in Ubuntu 18.04 file browser too. Simple solution
    – manikanta
    May 13, 2020 at 13:15
4

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.

3

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:

  1. You can store "hidden" extended attribute in selected files. See man attr

      attr -s hidden -V true your_file
    
  2. 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:

  1. 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.

  2. 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.

  3. 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)
    
1
  • ls.c lies in src, not the root directory, and there is no function lsdir in ls.c.
    – Melab
    Oct 3, 2015 at 17:54
2

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.

1
  • 4
    In OS X you can also hide files by chflags hidden filename.
    – slhck
    Nov 21, 2011 at 19:02
2

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.

1
  • This is going to lead to a very, very long string if more than a few files need to be hidden. For multiple files, there are more efficient ways to do this, but for a couple of files, a good solution nonetheless.
    – JW0914
    Nov 22, 2019 at 11:54
2

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 the opendir(), readdir(), …, closedir() sequence in one call. For each directory entry, the filldir() 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.

1

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.

1
  • And it is also untrue. While removing read permissions from a directory stops you from listing its contents, removing the execute permission will deny any access to the directory at all. When you don't have permission to execute a directory, you won't have access to anything beyond it. Not even if there's a subdirectory with full rights in it and you know its path.
    – Bachsau
    Apr 14, 2018 at 20:33
0

Add this to your .bashrc and your files won't be visible with ls command

function ls () {
     command ls "$@" -I fileA -I fileB
}
1
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Feb 8, 2023 at 15:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .