Will ls always list the files that rm will remove?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
30
down vote

favorite
1












Something I feel I ought to know for sure: if I ls <something>, will rm <something> remove exactly the same files that ls displayed? Are there any circumstances where rm could remove files that ls did not show? (This is in the 18.04 bash)



Edit: thank you to everyone who answered. I think the full answer is a combination of all the answers, so I have accepted the most up-voted answer as "the answer".



Unexpected things I have learned along the way:




  • ls is not as straightforward as you might think in its handling of its arguments

  • In a simple un-fiddled-with installation of Ubuntu, .bashrc aliases ls

  • Don't name your files beginning with a dash as they can look like command arguments, and naming one -r is asking for it!






share|improve this question


















  • 8




    I am somewhat surprised that rm does not have a --dry-run flag...
    – fkraiem
    Sep 5 at 10:19






  • 20




    @Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
    – marcelm
    Sep 5 at 10:53







  • 3




    @marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
    – Scribblemacher
    Sep 5 at 12:24






  • 5




    @Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
    – marcelm
    Sep 5 at 12:32







  • 12




    @Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
    – marcelm
    Sep 5 at 12:34














up vote
30
down vote

favorite
1












Something I feel I ought to know for sure: if I ls <something>, will rm <something> remove exactly the same files that ls displayed? Are there any circumstances where rm could remove files that ls did not show? (This is in the 18.04 bash)



Edit: thank you to everyone who answered. I think the full answer is a combination of all the answers, so I have accepted the most up-voted answer as "the answer".



Unexpected things I have learned along the way:




  • ls is not as straightforward as you might think in its handling of its arguments

  • In a simple un-fiddled-with installation of Ubuntu, .bashrc aliases ls

  • Don't name your files beginning with a dash as they can look like command arguments, and naming one -r is asking for it!






share|improve this question


















  • 8




    I am somewhat surprised that rm does not have a --dry-run flag...
    – fkraiem
    Sep 5 at 10:19






  • 20




    @Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
    – marcelm
    Sep 5 at 10:53







  • 3




    @marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
    – Scribblemacher
    Sep 5 at 12:24






  • 5




    @Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
    – marcelm
    Sep 5 at 12:32







  • 12




    @Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
    – marcelm
    Sep 5 at 12:34












up vote
30
down vote

favorite
1









up vote
30
down vote

favorite
1






1





Something I feel I ought to know for sure: if I ls <something>, will rm <something> remove exactly the same files that ls displayed? Are there any circumstances where rm could remove files that ls did not show? (This is in the 18.04 bash)



Edit: thank you to everyone who answered. I think the full answer is a combination of all the answers, so I have accepted the most up-voted answer as "the answer".



Unexpected things I have learned along the way:




  • ls is not as straightforward as you might think in its handling of its arguments

  • In a simple un-fiddled-with installation of Ubuntu, .bashrc aliases ls

  • Don't name your files beginning with a dash as they can look like command arguments, and naming one -r is asking for it!






share|improve this question














Something I feel I ought to know for sure: if I ls <something>, will rm <something> remove exactly the same files that ls displayed? Are there any circumstances where rm could remove files that ls did not show? (This is in the 18.04 bash)



Edit: thank you to everyone who answered. I think the full answer is a combination of all the answers, so I have accepted the most up-voted answer as "the answer".



Unexpected things I have learned along the way:




  • ls is not as straightforward as you might think in its handling of its arguments

  • In a simple un-fiddled-with installation of Ubuntu, .bashrc aliases ls

  • Don't name your files beginning with a dash as they can look like command arguments, and naming one -r is asking for it!








share|improve this question













share|improve this question




share|improve this question








edited Sep 8 at 5:25









JBMagination

34




34










asked Sep 5 at 9:25









B.Tanner

719712




719712







  • 8




    I am somewhat surprised that rm does not have a --dry-run flag...
    – fkraiem
    Sep 5 at 10:19






  • 20




    @Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
    – marcelm
    Sep 5 at 10:53







  • 3




    @marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
    – Scribblemacher
    Sep 5 at 12:24






  • 5




    @Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
    – marcelm
    Sep 5 at 12:32







  • 12




    @Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
    – marcelm
    Sep 5 at 12:34












  • 8




    I am somewhat surprised that rm does not have a --dry-run flag...
    – fkraiem
    Sep 5 at 10:19






  • 20




    @Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
    – marcelm
    Sep 5 at 10:53







  • 3




    @marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
    – Scribblemacher
    Sep 5 at 12:24






  • 5




    @Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
    – marcelm
    Sep 5 at 12:32







  • 12




    @Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
    – marcelm
    Sep 5 at 12:34







8




8




I am somewhat surprised that rm does not have a --dry-run flag...
– fkraiem
Sep 5 at 10:19




I am somewhat surprised that rm does not have a --dry-run flag...
– fkraiem
Sep 5 at 10:19




20




20




@Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
– marcelm
Sep 5 at 10:53





@Rinzwind Why would find -delete be better than rm? You say "That is why", but it's completely unclear to me what that refers to. Also note that your find invocation will delete all files recursively in the current directory, where rm will just delete the files in the immediate directory. Also -name * is a no-op. All in all, I'm quite puzzled by your advice...
– marcelm
Sep 5 at 10:53





3




3




@marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
– Scribblemacher
Sep 5 at 12:24




@marcelm I think the advice for using find is because you can run it, see all the files, and then run the same command with -delete. Since you already saw the results from find, there should be no ambiguity to what will be removed (I'd actually like to hear more details about this in the form of an answer)
– Scribblemacher
Sep 5 at 12:24




5




5




@Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
– marcelm
Sep 5 at 12:32





@Scribblemacher "... you can run it, see all the files, and then run the same command with -delete" - But how is that better than running ls <filespec>, followed by rm <filespec> (which the OP already knows how to do)?
– marcelm
Sep 5 at 12:32





12




12




@Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
– marcelm
Sep 5 at 12:34




@Rinzwind "That solves choroba's answer for instant where a file is created after ls and before rm." - No, it doesn't. If you run find ... -print first to confirm what files would be deleted, and then find ... -delete, you'll still delete files created between the two commands. If you use both -print and -delete, you don't get confirmation, just an after-the-fact report of what has been deleted (and you might as well use rm -v).
– marcelm
Sep 5 at 12:34










10 Answers
10






active

oldest

votes

















up vote
36
down vote



accepted










Well, both ls and rm operate on the arguments which are passed to them.



These arguments can be a simple file, so ls file.ext and rm file.ext operate on the same file and the outcome is clear (list the file / delete the file).



If instead argument is a directory, ls directory lists the content of the directory while rm directory won't work as is (i.e. rm without flags cannot remove directories, while if you do rm -r directory, it recursively deletes all files under directory and the directory itself.



But keep in mind that command line arguments can be subjected to shell expansion,
so it's not always guaranteed that the same arguments are passed to both commands
if they contain wildcards, variables, output from other commands, etc.



As an extreme example think ls $(rand).txt and rm $(rand).txt, the arguments are "the same" but the results are quite different!






share|improve this answer


















  • 3




    Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
    – Lightness Races in Orbit
    Sep 5 at 13:19






  • 4




    Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
    – Daniel Wagner
    Sep 6 at 12:46






  • 1




    @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
    – OrangeDog
    Sep 7 at 9:30


















up vote
19
down vote













If you're thinking of something like ls foo*.txt vs. rm foo*.txt, then yes, they will show and remove the same files. The shell expands the glob, and passes it to the command in question, and the commands work on the listed files. One listing them, one removing them.



The obvious difference is that if any of those files happened to be a directory, then ls would list its contents, but rm would fail to remove it. That's usually not a problem, since rm would remove less than what was shown by ls.



The big issue here comes from running ls * or rm * in a directory containing filenames starting with a dash. They would expand to the command lines of the two programs as if you wrote them out yourself, and ls would take -r to mean "reverse sort order", while rm would take -r to mean a recursive removal. The difference matters if you have subdirectories at least two levels deep. (ls * will show the contents of the first level directories, but rm -r * will everything past the first sublevel, too.)



To avoid that, write permissive globs with a leading ./ to indicate the current directory, and/or put a -- to signal the end of option processing before the glob (i.e. rm ./* or rm -- *).



With a glob like *.txt, that's actually not an issue since the dot is an invalid option character, and will cause an error (until someone expands the utilities to invent a meaning for it), but it's still safer to put the ./ there anyway.




Of course you could also get different results for the two commands if you changed the shell's globbing options, or created/moved/removed files in between the commands, but I doubt you meant any of those cases. (Dealing with new/moved files would be extremely messy to do safely.)






share|improve this answer
















  • 1




    Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
    – B.Tanner
    Sep 6 at 6:01






  • 1




    @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
    – ilkkachu
    Sep 6 at 8:03






  • 3




    I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
    – B.Tanner
    Sep 6 at 18:47

















up vote
16
down vote













Leaving aside shell behavior,let's focus on only what rm and ls can deal with themselves. At least one case where ls will show what rm can't remove involves directory permissions, and the other - special directories . and ...



Folder permissions



rm is an operation on a directory, because by removing a file, you're changing directory contents ( or in other words listing of directory entries,since directory is nothing more than a list of filenames and inodes). This means you need write permissions on a directory. Even if you are the owner of the file, without directory permissions you can't remove files. The reverse is also true: rm can remove files that may be owned by others, if you are directory owner.



So you may very well have read and execute permissions on a directory, which will allow you traverse the directory and view contents within just fine, for example ls /bin/echo, but you can't rm /bin/echo unless you are the owner of /bin or elevate your privileges with sudo.



And you'll see cases like this everywhere. Here's one such case: https://superuser.com/a/331124/418028




Special directories '.' and '..'



Another special case is . and .. directories. If you do ls . or ls .. , it will happily show you the contents, but rm'ing them is not allowed:



$ rm -rf .
rm: refusing to remove '.' or '..' directory: skipping '.'





share|improve this answer





























    up vote
    15
    down vote













    If you type ls * and then rm *, it's possible you'll remove more files than ls showed - they might have been created in the tiny time interval between the end of ls and start of rm.






    share|improve this answer
















    • 1




      That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
      – Sergiy Kolodyazhnyy
      Sep 5 at 9:52






    • 1




      @OrangeDog You're missing the point. We're talking about race condition
      – Sergiy Kolodyazhnyy
      Sep 7 at 15:51







    • 1




      @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
      – Sergiy Kolodyazhnyy
      Sep 7 at 16:09






    • 1




      Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
      – OrangeDog
      Sep 7 at 16:22






    • 1




      @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
      – Sergiy Kolodyazhnyy
      Sep 7 at 16:59

















    up vote
    9
    down vote













    ls * and rm * are not responsible for expanding the glob - that's done by the shell before passing it to the command.



    This means that you can use any command with the expanded filelist - so I would use something that does as little as possible.



    So a better way to do this (or at the least, another way) is to skip the middle-man.



    echo * will show you exactly what would be passed to your rm command.






    share|improve this answer










    New contributor




    Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.













    • 2




      Thank you, I like the idea of using echo instead of ls in this scenario.
      – B.Tanner
      Sep 6 at 6:09






    • 3




      Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
      – ilkkachu
      Sep 6 at 8:10

















    up vote
    4
    down vote













    How about:



    $ mkdir what
    $ cd what
    $ mkdir -p huh/uhm ./-r
    $ ls *
    uhm
    $ rm *
    $ ls
    -r
    $ ls -R
    .:
    -r

    ./-r:


    Basically wildcards expanding to stuff starting with - (or manually entered stuff starting with - but that looks a bit more like cheating) may be interpreted differently by ls and rm.






    share|improve this answer



























      up vote
      4
      down vote













      There are edge cases where what ls shows is not what rm removes. A rather extreme, but fortunately benign one is if the argument you pass is a symbolic link to a directory: ls will show you all the files in the symlinked directory, while rm will remove the symlink, leaving the original directory and its contents untouched:



      % ln -s $HOME some_link
      % ls some_link # Will display directory contents
      bin lib Desktop ...
      % rm some_link
      % ls $HOME
      bin lib Desktop ...





      share|improve this answer
















      • 1




        Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
        – marcelm
        Sep 6 at 21:55










      • Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
        – alexis
        Sep 6 at 22:03






      • 1




        Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
        – alexis
        Sep 6 at 22:03










      • If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
        – G-Man
        2 days ago










      • Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
        – alexis
        2 days ago

















      up vote
      4
      down vote













      If you do only ls instead of ls -a, yes rm can remove hidden files you haven't seen with ls without -a.



      Example :



      According to :



      dir_test
      ├── .test
      └── test2


      ls dir_test : will display only test2



      ls -A dir_test : will display test2 + .test



      rm -r dir_test : will remove all (.test + test2)



      I hope that will help you.






      share|improve this answer










      New contributor




      DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.

















      • Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
        – marcelm
        Sep 5 at 10:56










      • No, ls * don't display hidden files.
        – DevHugo
        Sep 5 at 13:31










      • But yes it's a little bit confused, I added some examples.
        – DevHugo
        Sep 5 at 13:38






      • 1




        ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
        – G-Man
        2 days ago

















      up vote
      3
      down vote













      There are already many good answers, but I want to add some more deep insight.



      Ask yourself the question: How many parameters are passed to ls, if you write



      ls *


      ...? Note that the ls command does not get the * as parameter if there are any files that * can be expanded to. Instead, the shell first performs globbing before invoking the command, so the ls command actually gets as many parameters as there are files matched by the globbing. To suppress globbing, quote the parameter.



      This is true for any command: echo * vs echo '*'.



      There is a script, call it countparams.sh to test the effect. It tells you how many parameters it got passed and lists them.



      #!/bin/bash
      echo "This script was given $# parameters."
      arr=( "$@" )
      for ((i=0;i<$#;i++)); do
      echo "Parameter $((i+1)): $arr[$i]"
      done


      Make it executable and run ./countparams.sh *. Learn from its output!






      share|improve this answer





























        up vote
        1
        down vote













        The glob will expand the same way both times, if the directory contents are the same at those two different times.




        If you really want to check what will be removed, use rm -i *.txt. It will prompt you separately for each file before (trying to) remove it.



        This is guaranteed to be safe against race conditions:

                ls *.txt / a new file is created / rm *.txt

        because you're prompted for every file by the same program that's doing the removal.




        This is too cumbersome for normal use, and if you alias rm to rm -i, you'll find yourself using rm or rm -f fairly often. But it is worth at least mentioning that there is a solution to the race condition. (It's even portable to non-GNU systems: POSIX rm(1) specifies the -i option.)



        Another option would be a bash array: to_remove=(*.txt), then ask the user to confirm (perhaps after doing ls -ld -- "$to_remove[@]"), then
        rm -- "$to_remove[@]". So glob expansion is only done once, and the list is passed verbatim to rm.



        Another practically-usable option is GNU rm -I (man page), which prompts if removing more than 4 items. (But doesn't show you the list, just the total.) I use alias rm='rm -I' on my desktop.



        It's a nice safeguard against fat-fingering return with a half-typed pattern that matches too much. But using ls first is generally good in a directory you own, or on a single-user system, and when there aren't background processes that could asynchronously create new files there. To guard against fat-fingering, don't type rm -rf /foo/bar/baz from left to right. rm -rf / is special-cased, but rm -rf /usr isn't!  Leave out the -rf part, or start with ls, and only add the rm -rf part after typing the path.






        share|improve this answer






















          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "89"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1072300%2fwill-ls-always-list-the-files-that-rm-will-remove%23new-answer', 'question_page');

          );

          Post as a guest






























          10 Answers
          10






          active

          oldest

          votes








          10 Answers
          10






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          36
          down vote



          accepted










          Well, both ls and rm operate on the arguments which are passed to them.



          These arguments can be a simple file, so ls file.ext and rm file.ext operate on the same file and the outcome is clear (list the file / delete the file).



          If instead argument is a directory, ls directory lists the content of the directory while rm directory won't work as is (i.e. rm without flags cannot remove directories, while if you do rm -r directory, it recursively deletes all files under directory and the directory itself.



          But keep in mind that command line arguments can be subjected to shell expansion,
          so it's not always guaranteed that the same arguments are passed to both commands
          if they contain wildcards, variables, output from other commands, etc.



          As an extreme example think ls $(rand).txt and rm $(rand).txt, the arguments are "the same" but the results are quite different!






          share|improve this answer


















          • 3




            Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
            – Lightness Races in Orbit
            Sep 5 at 13:19






          • 4




            Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
            – Daniel Wagner
            Sep 6 at 12:46






          • 1




            @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
            – OrangeDog
            Sep 7 at 9:30















          up vote
          36
          down vote



          accepted










          Well, both ls and rm operate on the arguments which are passed to them.



          These arguments can be a simple file, so ls file.ext and rm file.ext operate on the same file and the outcome is clear (list the file / delete the file).



          If instead argument is a directory, ls directory lists the content of the directory while rm directory won't work as is (i.e. rm without flags cannot remove directories, while if you do rm -r directory, it recursively deletes all files under directory and the directory itself.



          But keep in mind that command line arguments can be subjected to shell expansion,
          so it's not always guaranteed that the same arguments are passed to both commands
          if they contain wildcards, variables, output from other commands, etc.



          As an extreme example think ls $(rand).txt and rm $(rand).txt, the arguments are "the same" but the results are quite different!






          share|improve this answer


















          • 3




            Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
            – Lightness Races in Orbit
            Sep 5 at 13:19






          • 4




            Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
            – Daniel Wagner
            Sep 6 at 12:46






          • 1




            @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
            – OrangeDog
            Sep 7 at 9:30













          up vote
          36
          down vote



          accepted







          up vote
          36
          down vote



          accepted






          Well, both ls and rm operate on the arguments which are passed to them.



          These arguments can be a simple file, so ls file.ext and rm file.ext operate on the same file and the outcome is clear (list the file / delete the file).



          If instead argument is a directory, ls directory lists the content of the directory while rm directory won't work as is (i.e. rm without flags cannot remove directories, while if you do rm -r directory, it recursively deletes all files under directory and the directory itself.



          But keep in mind that command line arguments can be subjected to shell expansion,
          so it's not always guaranteed that the same arguments are passed to both commands
          if they contain wildcards, variables, output from other commands, etc.



          As an extreme example think ls $(rand).txt and rm $(rand).txt, the arguments are "the same" but the results are quite different!






          share|improve this answer














          Well, both ls and rm operate on the arguments which are passed to them.



          These arguments can be a simple file, so ls file.ext and rm file.ext operate on the same file and the outcome is clear (list the file / delete the file).



          If instead argument is a directory, ls directory lists the content of the directory while rm directory won't work as is (i.e. rm without flags cannot remove directories, while if you do rm -r directory, it recursively deletes all files under directory and the directory itself.



          But keep in mind that command line arguments can be subjected to shell expansion,
          so it's not always guaranteed that the same arguments are passed to both commands
          if they contain wildcards, variables, output from other commands, etc.



          As an extreme example think ls $(rand).txt and rm $(rand).txt, the arguments are "the same" but the results are quite different!







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Sep 5 at 11:06

























          answered Sep 5 at 9:36









          Mr Shunz

          1,6891217




          1,6891217







          • 3




            Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
            – Lightness Races in Orbit
            Sep 5 at 13:19






          • 4




            Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
            – Daniel Wagner
            Sep 6 at 12:46






          • 1




            @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
            – OrangeDog
            Sep 7 at 9:30













          • 3




            Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
            – Lightness Races in Orbit
            Sep 5 at 13:19






          • 4




            Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
            – Daniel Wagner
            Sep 6 at 12:46






          • 1




            @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
            – OrangeDog
            Sep 7 at 9:30








          3




          3




          Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
          – Lightness Races in Orbit
          Sep 5 at 13:19




          Also consider ls vs rm * where there are "hidden" (dot) files, though even that's not at all a fair comparison as I didn't write ls *. But rm is meaningless on its own so the entire thing is apples and oranges really. If I've understood correctly, that's the crux of your answer, so good job :)
          – Lightness Races in Orbit
          Sep 5 at 13:19




          4




          4




          Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
          – Daniel Wagner
          Sep 6 at 12:46




          Another comment on ls vs rm -r: the command ls <directory> will not show hidden files inside the directory, but rm -r <directory> will delete even the hidden files.
          – Daniel Wagner
          Sep 6 at 12:46




          1




          1




          @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
          – OrangeDog
          Sep 7 at 9:30





          @LightnessRacesinOrbit ls won't list them (unless it's aliased to ls -a), and rm * won't delete them (unless you have dotglob set).
          – OrangeDog
          Sep 7 at 9:30













          up vote
          19
          down vote













          If you're thinking of something like ls foo*.txt vs. rm foo*.txt, then yes, they will show and remove the same files. The shell expands the glob, and passes it to the command in question, and the commands work on the listed files. One listing them, one removing them.



          The obvious difference is that if any of those files happened to be a directory, then ls would list its contents, but rm would fail to remove it. That's usually not a problem, since rm would remove less than what was shown by ls.



          The big issue here comes from running ls * or rm * in a directory containing filenames starting with a dash. They would expand to the command lines of the two programs as if you wrote them out yourself, and ls would take -r to mean "reverse sort order", while rm would take -r to mean a recursive removal. The difference matters if you have subdirectories at least two levels deep. (ls * will show the contents of the first level directories, but rm -r * will everything past the first sublevel, too.)



          To avoid that, write permissive globs with a leading ./ to indicate the current directory, and/or put a -- to signal the end of option processing before the glob (i.e. rm ./* or rm -- *).



          With a glob like *.txt, that's actually not an issue since the dot is an invalid option character, and will cause an error (until someone expands the utilities to invent a meaning for it), but it's still safer to put the ./ there anyway.




          Of course you could also get different results for the two commands if you changed the shell's globbing options, or created/moved/removed files in between the commands, but I doubt you meant any of those cases. (Dealing with new/moved files would be extremely messy to do safely.)






          share|improve this answer
















          • 1




            Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
            – B.Tanner
            Sep 6 at 6:01






          • 1




            @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
            – ilkkachu
            Sep 6 at 8:03






          • 3




            I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
            – B.Tanner
            Sep 6 at 18:47














          up vote
          19
          down vote













          If you're thinking of something like ls foo*.txt vs. rm foo*.txt, then yes, they will show and remove the same files. The shell expands the glob, and passes it to the command in question, and the commands work on the listed files. One listing them, one removing them.



          The obvious difference is that if any of those files happened to be a directory, then ls would list its contents, but rm would fail to remove it. That's usually not a problem, since rm would remove less than what was shown by ls.



          The big issue here comes from running ls * or rm * in a directory containing filenames starting with a dash. They would expand to the command lines of the two programs as if you wrote them out yourself, and ls would take -r to mean "reverse sort order", while rm would take -r to mean a recursive removal. The difference matters if you have subdirectories at least two levels deep. (ls * will show the contents of the first level directories, but rm -r * will everything past the first sublevel, too.)



          To avoid that, write permissive globs with a leading ./ to indicate the current directory, and/or put a -- to signal the end of option processing before the glob (i.e. rm ./* or rm -- *).



          With a glob like *.txt, that's actually not an issue since the dot is an invalid option character, and will cause an error (until someone expands the utilities to invent a meaning for it), but it's still safer to put the ./ there anyway.




          Of course you could also get different results for the two commands if you changed the shell's globbing options, or created/moved/removed files in between the commands, but I doubt you meant any of those cases. (Dealing with new/moved files would be extremely messy to do safely.)






          share|improve this answer
















          • 1




            Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
            – B.Tanner
            Sep 6 at 6:01






          • 1




            @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
            – ilkkachu
            Sep 6 at 8:03






          • 3




            I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
            – B.Tanner
            Sep 6 at 18:47












          up vote
          19
          down vote










          up vote
          19
          down vote









          If you're thinking of something like ls foo*.txt vs. rm foo*.txt, then yes, they will show and remove the same files. The shell expands the glob, and passes it to the command in question, and the commands work on the listed files. One listing them, one removing them.



          The obvious difference is that if any of those files happened to be a directory, then ls would list its contents, but rm would fail to remove it. That's usually not a problem, since rm would remove less than what was shown by ls.



          The big issue here comes from running ls * or rm * in a directory containing filenames starting with a dash. They would expand to the command lines of the two programs as if you wrote them out yourself, and ls would take -r to mean "reverse sort order", while rm would take -r to mean a recursive removal. The difference matters if you have subdirectories at least two levels deep. (ls * will show the contents of the first level directories, but rm -r * will everything past the first sublevel, too.)



          To avoid that, write permissive globs with a leading ./ to indicate the current directory, and/or put a -- to signal the end of option processing before the glob (i.e. rm ./* or rm -- *).



          With a glob like *.txt, that's actually not an issue since the dot is an invalid option character, and will cause an error (until someone expands the utilities to invent a meaning for it), but it's still safer to put the ./ there anyway.




          Of course you could also get different results for the two commands if you changed the shell's globbing options, or created/moved/removed files in between the commands, but I doubt you meant any of those cases. (Dealing with new/moved files would be extremely messy to do safely.)






          share|improve this answer












          If you're thinking of something like ls foo*.txt vs. rm foo*.txt, then yes, they will show and remove the same files. The shell expands the glob, and passes it to the command in question, and the commands work on the listed files. One listing them, one removing them.



          The obvious difference is that if any of those files happened to be a directory, then ls would list its contents, but rm would fail to remove it. That's usually not a problem, since rm would remove less than what was shown by ls.



          The big issue here comes from running ls * or rm * in a directory containing filenames starting with a dash. They would expand to the command lines of the two programs as if you wrote them out yourself, and ls would take -r to mean "reverse sort order", while rm would take -r to mean a recursive removal. The difference matters if you have subdirectories at least two levels deep. (ls * will show the contents of the first level directories, but rm -r * will everything past the first sublevel, too.)



          To avoid that, write permissive globs with a leading ./ to indicate the current directory, and/or put a -- to signal the end of option processing before the glob (i.e. rm ./* or rm -- *).



          With a glob like *.txt, that's actually not an issue since the dot is an invalid option character, and will cause an error (until someone expands the utilities to invent a meaning for it), but it's still safer to put the ./ there anyway.




          Of course you could also get different results for the two commands if you changed the shell's globbing options, or created/moved/removed files in between the commands, but I doubt you meant any of those cases. (Dealing with new/moved files would be extremely messy to do safely.)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Sep 5 at 22:56









          ilkkachu

          971210




          971210







          • 1




            Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
            – B.Tanner
            Sep 6 at 6:01






          • 1




            @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
            – ilkkachu
            Sep 6 at 8:03






          • 3




            I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
            – B.Tanner
            Sep 6 at 18:47












          • 1




            Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
            – B.Tanner
            Sep 6 at 6:01






          • 1




            @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
            – ilkkachu
            Sep 6 at 8:03






          • 3




            I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
            – B.Tanner
            Sep 6 at 18:47







          1




          1




          Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
          – B.Tanner
          Sep 6 at 6:01




          Thank you. This seems to highlight an issue with the whole command line syntax: if you name files starting with a dash you are sailing in dangerous waters. Who knows what commands you might use in the future, long after you've forgotten about the - files.
          – B.Tanner
          Sep 6 at 6:01




          1




          1




          @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
          – ilkkachu
          Sep 6 at 8:03




          @B.Tanner, yes. In a sense, the problem is that the command line arguments are just plain strings. If the system was designed today, there might be more structure in it so that the executed program could know if an argument was supposed to be an option flag or not. There are also other problems that come from the very lax structure of filenames. There's a very thorough essay on that by dwheeler, but I have to warn that reading it is going to hurt. (Either from the detail, or from the utter awfulness of what can go wrong.)
          – ilkkachu
          Sep 6 at 8:03




          3




          3




          I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
          – B.Tanner
          Sep 6 at 18:47




          I can't resist, you've sold it to me, I'm off to read it now, with memories of the time I managed to get a carriage return character at the end of lots of filenames (trying to see if I could construct a Windows batch file that can also run as a bash script...I didn't see that one coming!)
          – B.Tanner
          Sep 6 at 18:47










          up vote
          16
          down vote













          Leaving aside shell behavior,let's focus on only what rm and ls can deal with themselves. At least one case where ls will show what rm can't remove involves directory permissions, and the other - special directories . and ...



          Folder permissions



          rm is an operation on a directory, because by removing a file, you're changing directory contents ( or in other words listing of directory entries,since directory is nothing more than a list of filenames and inodes). This means you need write permissions on a directory. Even if you are the owner of the file, without directory permissions you can't remove files. The reverse is also true: rm can remove files that may be owned by others, if you are directory owner.



          So you may very well have read and execute permissions on a directory, which will allow you traverse the directory and view contents within just fine, for example ls /bin/echo, but you can't rm /bin/echo unless you are the owner of /bin or elevate your privileges with sudo.



          And you'll see cases like this everywhere. Here's one such case: https://superuser.com/a/331124/418028




          Special directories '.' and '..'



          Another special case is . and .. directories. If you do ls . or ls .. , it will happily show you the contents, but rm'ing them is not allowed:



          $ rm -rf .
          rm: refusing to remove '.' or '..' directory: skipping '.'





          share|improve this answer


























            up vote
            16
            down vote













            Leaving aside shell behavior,let's focus on only what rm and ls can deal with themselves. At least one case where ls will show what rm can't remove involves directory permissions, and the other - special directories . and ...



            Folder permissions



            rm is an operation on a directory, because by removing a file, you're changing directory contents ( or in other words listing of directory entries,since directory is nothing more than a list of filenames and inodes). This means you need write permissions on a directory. Even if you are the owner of the file, without directory permissions you can't remove files. The reverse is also true: rm can remove files that may be owned by others, if you are directory owner.



            So you may very well have read and execute permissions on a directory, which will allow you traverse the directory and view contents within just fine, for example ls /bin/echo, but you can't rm /bin/echo unless you are the owner of /bin or elevate your privileges with sudo.



            And you'll see cases like this everywhere. Here's one such case: https://superuser.com/a/331124/418028




            Special directories '.' and '..'



            Another special case is . and .. directories. If you do ls . or ls .. , it will happily show you the contents, but rm'ing them is not allowed:



            $ rm -rf .
            rm: refusing to remove '.' or '..' directory: skipping '.'





            share|improve this answer
























              up vote
              16
              down vote










              up vote
              16
              down vote









              Leaving aside shell behavior,let's focus on only what rm and ls can deal with themselves. At least one case where ls will show what rm can't remove involves directory permissions, and the other - special directories . and ...



              Folder permissions



              rm is an operation on a directory, because by removing a file, you're changing directory contents ( or in other words listing of directory entries,since directory is nothing more than a list of filenames and inodes). This means you need write permissions on a directory. Even if you are the owner of the file, without directory permissions you can't remove files. The reverse is also true: rm can remove files that may be owned by others, if you are directory owner.



              So you may very well have read and execute permissions on a directory, which will allow you traverse the directory and view contents within just fine, for example ls /bin/echo, but you can't rm /bin/echo unless you are the owner of /bin or elevate your privileges with sudo.



              And you'll see cases like this everywhere. Here's one such case: https://superuser.com/a/331124/418028




              Special directories '.' and '..'



              Another special case is . and .. directories. If you do ls . or ls .. , it will happily show you the contents, but rm'ing them is not allowed:



              $ rm -rf .
              rm: refusing to remove '.' or '..' directory: skipping '.'





              share|improve this answer














              Leaving aside shell behavior,let's focus on only what rm and ls can deal with themselves. At least one case where ls will show what rm can't remove involves directory permissions, and the other - special directories . and ...



              Folder permissions



              rm is an operation on a directory, because by removing a file, you're changing directory contents ( or in other words listing of directory entries,since directory is nothing more than a list of filenames and inodes). This means you need write permissions on a directory. Even if you are the owner of the file, without directory permissions you can't remove files. The reverse is also true: rm can remove files that may be owned by others, if you are directory owner.



              So you may very well have read and execute permissions on a directory, which will allow you traverse the directory and view contents within just fine, for example ls /bin/echo, but you can't rm /bin/echo unless you are the owner of /bin or elevate your privileges with sudo.



              And you'll see cases like this everywhere. Here's one such case: https://superuser.com/a/331124/418028




              Special directories '.' and '..'



              Another special case is . and .. directories. If you do ls . or ls .. , it will happily show you the contents, but rm'ing them is not allowed:



              $ rm -rf .
              rm: refusing to remove '.' or '..' directory: skipping '.'






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited yesterday

























              answered Sep 5 at 9:42









              Sergiy Kolodyazhnyy

              64.9k9129282




              64.9k9129282




















                  up vote
                  15
                  down vote













                  If you type ls * and then rm *, it's possible you'll remove more files than ls showed - they might have been created in the tiny time interval between the end of ls and start of rm.






                  share|improve this answer
















                  • 1




                    That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                    – Sergiy Kolodyazhnyy
                    Sep 5 at 9:52






                  • 1




                    @OrangeDog You're missing the point. We're talking about race condition
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 15:51







                  • 1




                    @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:09






                  • 1




                    Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                    – OrangeDog
                    Sep 7 at 16:22






                  • 1




                    @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:59














                  up vote
                  15
                  down vote













                  If you type ls * and then rm *, it's possible you'll remove more files than ls showed - they might have been created in the tiny time interval between the end of ls and start of rm.






                  share|improve this answer
















                  • 1




                    That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                    – Sergiy Kolodyazhnyy
                    Sep 5 at 9:52






                  • 1




                    @OrangeDog You're missing the point. We're talking about race condition
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 15:51







                  • 1




                    @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:09






                  • 1




                    Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                    – OrangeDog
                    Sep 7 at 16:22






                  • 1




                    @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:59












                  up vote
                  15
                  down vote










                  up vote
                  15
                  down vote









                  If you type ls * and then rm *, it's possible you'll remove more files than ls showed - they might have been created in the tiny time interval between the end of ls and start of rm.






                  share|improve this answer












                  If you type ls * and then rm *, it's possible you'll remove more files than ls showed - they might have been created in the tiny time interval between the end of ls and start of rm.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 5 at 9:38









                  choroba

                  6,07411728




                  6,07411728







                  • 1




                    That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                    – Sergiy Kolodyazhnyy
                    Sep 5 at 9:52






                  • 1




                    @OrangeDog You're missing the point. We're talking about race condition
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 15:51







                  • 1




                    @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:09






                  • 1




                    Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                    – OrangeDog
                    Sep 7 at 16:22






                  • 1




                    @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:59












                  • 1




                    That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                    – Sergiy Kolodyazhnyy
                    Sep 5 at 9:52






                  • 1




                    @OrangeDog You're missing the point. We're talking about race condition
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 15:51







                  • 1




                    @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:09






                  • 1




                    Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                    – OrangeDog
                    Sep 7 at 16:22






                  • 1




                    @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                    – Sergiy Kolodyazhnyy
                    Sep 7 at 16:59







                  1




                  1




                  That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                  – Sergiy Kolodyazhnyy
                  Sep 5 at 9:52




                  That's a probable case for /tmp, where many applications can create temporary files, so that's always a possibility in both commands with *. However, some applications also make files anonymous by unlink() ing them while keeping file handle open, so it may show in ls * but rm * may not catch it.
                  – Sergiy Kolodyazhnyy
                  Sep 5 at 9:52




                  1




                  1




                  @OrangeDog You're missing the point. We're talking about race condition
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 15:51





                  @OrangeDog You're missing the point. We're talking about race condition
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 15:51





                  1




                  1




                  @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 16:09




                  @OrangeDog I'll need to verify this since I'm on the phone right now, but the point still stands even with * there's difference between what ls would show and what rm operates on, because listing of directory contents has changed in between.
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 16:09




                  1




                  1




                  Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                  – OrangeDog
                  Sep 7 at 16:22




                  Even if you only do one command, there’s a race condition between expanding the arguments and then deleting them.
                  – OrangeDog
                  Sep 7 at 16:22




                  1




                  1




                  @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 16:59




                  @OrangeDog I can agree with that. As wildcard expansion works on existing filenames, yes, there's a race condition between shell expanding the wildcard, and a command processing it, so ls * could in fact show filename that already is gone.
                  – Sergiy Kolodyazhnyy
                  Sep 7 at 16:59










                  up vote
                  9
                  down vote













                  ls * and rm * are not responsible for expanding the glob - that's done by the shell before passing it to the command.



                  This means that you can use any command with the expanded filelist - so I would use something that does as little as possible.



                  So a better way to do this (or at the least, another way) is to skip the middle-man.



                  echo * will show you exactly what would be passed to your rm command.






                  share|improve this answer










                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.













                  • 2




                    Thank you, I like the idea of using echo instead of ls in this scenario.
                    – B.Tanner
                    Sep 6 at 6:09






                  • 3




                    Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                    – ilkkachu
                    Sep 6 at 8:10














                  up vote
                  9
                  down vote













                  ls * and rm * are not responsible for expanding the glob - that's done by the shell before passing it to the command.



                  This means that you can use any command with the expanded filelist - so I would use something that does as little as possible.



                  So a better way to do this (or at the least, another way) is to skip the middle-man.



                  echo * will show you exactly what would be passed to your rm command.






                  share|improve this answer










                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.













                  • 2




                    Thank you, I like the idea of using echo instead of ls in this scenario.
                    – B.Tanner
                    Sep 6 at 6:09






                  • 3




                    Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                    – ilkkachu
                    Sep 6 at 8:10












                  up vote
                  9
                  down vote










                  up vote
                  9
                  down vote









                  ls * and rm * are not responsible for expanding the glob - that's done by the shell before passing it to the command.



                  This means that you can use any command with the expanded filelist - so I would use something that does as little as possible.



                  So a better way to do this (or at the least, another way) is to skip the middle-man.



                  echo * will show you exactly what would be passed to your rm command.






                  share|improve this answer










                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  ls * and rm * are not responsible for expanding the glob - that's done by the shell before passing it to the command.



                  This means that you can use any command with the expanded filelist - so I would use something that does as little as possible.



                  So a better way to do this (or at the least, another way) is to skip the middle-man.



                  echo * will show you exactly what would be passed to your rm command.







                  share|improve this answer










                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  share|improve this answer



                  share|improve this answer








                  edited yesterday





















                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  answered Sep 6 at 0:30









                  Shadow

                  1935




                  1935




                  New contributor




                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.





                  New contributor





                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






                  Shadow is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.







                  • 2




                    Thank you, I like the idea of using echo instead of ls in this scenario.
                    – B.Tanner
                    Sep 6 at 6:09






                  • 3




                    Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                    – ilkkachu
                    Sep 6 at 8:10












                  • 2




                    Thank you, I like the idea of using echo instead of ls in this scenario.
                    – B.Tanner
                    Sep 6 at 6:09






                  • 3




                    Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                    – ilkkachu
                    Sep 6 at 8:10







                  2




                  2




                  Thank you, I like the idea of using echo instead of ls in this scenario.
                  – B.Tanner
                  Sep 6 at 6:09




                  Thank you, I like the idea of using echo instead of ls in this scenario.
                  – B.Tanner
                  Sep 6 at 6:09




                  3




                  3




                  Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                  – ilkkachu
                  Sep 6 at 8:10




                  Or printf "%sn" * to get an unambiguous view on filenames with spaces. (Or %q instead to deal with newlines and control characters too, at the expense of uglier output.)
                  – ilkkachu
                  Sep 6 at 8:10










                  up vote
                  4
                  down vote













                  How about:



                  $ mkdir what
                  $ cd what
                  $ mkdir -p huh/uhm ./-r
                  $ ls *
                  uhm
                  $ rm *
                  $ ls
                  -r
                  $ ls -R
                  .:
                  -r

                  ./-r:


                  Basically wildcards expanding to stuff starting with - (or manually entered stuff starting with - but that looks a bit more like cheating) may be interpreted differently by ls and rm.






                  share|improve this answer
























                    up vote
                    4
                    down vote













                    How about:



                    $ mkdir what
                    $ cd what
                    $ mkdir -p huh/uhm ./-r
                    $ ls *
                    uhm
                    $ rm *
                    $ ls
                    -r
                    $ ls -R
                    .:
                    -r

                    ./-r:


                    Basically wildcards expanding to stuff starting with - (or manually entered stuff starting with - but that looks a bit more like cheating) may be interpreted differently by ls and rm.






                    share|improve this answer






















                      up vote
                      4
                      down vote










                      up vote
                      4
                      down vote









                      How about:



                      $ mkdir what
                      $ cd what
                      $ mkdir -p huh/uhm ./-r
                      $ ls *
                      uhm
                      $ rm *
                      $ ls
                      -r
                      $ ls -R
                      .:
                      -r

                      ./-r:


                      Basically wildcards expanding to stuff starting with - (or manually entered stuff starting with - but that looks a bit more like cheating) may be interpreted differently by ls and rm.






                      share|improve this answer












                      How about:



                      $ mkdir what
                      $ cd what
                      $ mkdir -p huh/uhm ./-r
                      $ ls *
                      uhm
                      $ rm *
                      $ ls
                      -r
                      $ ls -R
                      .:
                      -r

                      ./-r:


                      Basically wildcards expanding to stuff starting with - (or manually entered stuff starting with - but that looks a bit more like cheating) may be interpreted differently by ls and rm.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Sep 5 at 12:19







                      user868053



























                          up vote
                          4
                          down vote













                          There are edge cases where what ls shows is not what rm removes. A rather extreme, but fortunately benign one is if the argument you pass is a symbolic link to a directory: ls will show you all the files in the symlinked directory, while rm will remove the symlink, leaving the original directory and its contents untouched:



                          % ln -s $HOME some_link
                          % ls some_link # Will display directory contents
                          bin lib Desktop ...
                          % rm some_link
                          % ls $HOME
                          bin lib Desktop ...





                          share|improve this answer
















                          • 1




                            Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                            – marcelm
                            Sep 6 at 21:55










                          • Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                            – alexis
                            Sep 6 at 22:03






                          • 1




                            Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                            – alexis
                            Sep 6 at 22:03










                          • If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                            – G-Man
                            2 days ago










                          • Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                            – alexis
                            2 days ago














                          up vote
                          4
                          down vote













                          There are edge cases where what ls shows is not what rm removes. A rather extreme, but fortunately benign one is if the argument you pass is a symbolic link to a directory: ls will show you all the files in the symlinked directory, while rm will remove the symlink, leaving the original directory and its contents untouched:



                          % ln -s $HOME some_link
                          % ls some_link # Will display directory contents
                          bin lib Desktop ...
                          % rm some_link
                          % ls $HOME
                          bin lib Desktop ...





                          share|improve this answer
















                          • 1




                            Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                            – marcelm
                            Sep 6 at 21:55










                          • Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                            – alexis
                            Sep 6 at 22:03






                          • 1




                            Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                            – alexis
                            Sep 6 at 22:03










                          • If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                            – G-Man
                            2 days ago










                          • Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                            – alexis
                            2 days ago












                          up vote
                          4
                          down vote










                          up vote
                          4
                          down vote









                          There are edge cases where what ls shows is not what rm removes. A rather extreme, but fortunately benign one is if the argument you pass is a symbolic link to a directory: ls will show you all the files in the symlinked directory, while rm will remove the symlink, leaving the original directory and its contents untouched:



                          % ln -s $HOME some_link
                          % ls some_link # Will display directory contents
                          bin lib Desktop ...
                          % rm some_link
                          % ls $HOME
                          bin lib Desktop ...





                          share|improve this answer












                          There are edge cases where what ls shows is not what rm removes. A rather extreme, but fortunately benign one is if the argument you pass is a symbolic link to a directory: ls will show you all the files in the symlinked directory, while rm will remove the symlink, leaving the original directory and its contents untouched:



                          % ln -s $HOME some_link
                          % ls some_link # Will display directory contents
                          bin lib Desktop ...
                          % rm some_link
                          % ls $HOME
                          bin lib Desktop ...






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Sep 6 at 20:07









                          alexis

                          90068




                          90068







                          • 1




                            Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                            – marcelm
                            Sep 6 at 21:55










                          • Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                            – alexis
                            Sep 6 at 22:03






                          • 1




                            Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                            – alexis
                            Sep 6 at 22:03










                          • If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                            – G-Man
                            2 days ago










                          • Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                            – alexis
                            2 days ago












                          • 1




                            Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                            – marcelm
                            Sep 6 at 21:55










                          • Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                            – alexis
                            Sep 6 at 22:03






                          • 1




                            Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                            – alexis
                            Sep 6 at 22:03










                          • If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                            – G-Man
                            2 days ago










                          • Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                            – alexis
                            2 days ago







                          1




                          1




                          Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                          – marcelm
                          Sep 6 at 21:55




                          Huh. ln -s $HOME some_link; ls some_link outputs some_link@ for me, but I have ls aliased to ls -F. Apparently, -F changes the behaviour to showing the link instead of dereferencing it. Did not expect that.
                          – marcelm
                          Sep 6 at 21:55












                          Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                          – alexis
                          Sep 6 at 22:03




                          Indeed! Also ls -l for example targets the link, not the destination... there have to be ways to inspect the link itself.
                          – alexis
                          Sep 6 at 22:03




                          1




                          1




                          Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                          – alexis
                          Sep 6 at 22:03




                          Adding options to the question opens up too many possibilities-- my answer is about the unmodified behavior of ls and rm.
                          – alexis
                          Sep 6 at 22:03












                          If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                          – G-Man
                          2 days ago




                          If you say ls some_link/, ls -H some_link, or ls -L some_link, it will list the linked-to directory, even if you add -F or -l.  Conversely (sort-of), -d says to look at a directory rather than its contents; compare ls -l /tmp and ls -ld /tmp.
                          – G-Man
                          2 days ago












                          Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                          – alexis
                          2 days ago




                          Sure, you can add flags that change the behavior of ls. You're basically showing why enumerating behaviors with different flags is not worth the bother for this question...
                          – alexis
                          2 days ago










                          up vote
                          4
                          down vote













                          If you do only ls instead of ls -a, yes rm can remove hidden files you haven't seen with ls without -a.



                          Example :



                          According to :



                          dir_test
                          ├── .test
                          └── test2


                          ls dir_test : will display only test2



                          ls -A dir_test : will display test2 + .test



                          rm -r dir_test : will remove all (.test + test2)



                          I hope that will help you.






                          share|improve this answer










                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.

















                          • Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                            – marcelm
                            Sep 5 at 10:56










                          • No, ls * don't display hidden files.
                            – DevHugo
                            Sep 5 at 13:31










                          • But yes it's a little bit confused, I added some examples.
                            – DevHugo
                            Sep 5 at 13:38






                          • 1




                            ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                            – G-Man
                            2 days ago














                          up vote
                          4
                          down vote













                          If you do only ls instead of ls -a, yes rm can remove hidden files you haven't seen with ls without -a.



                          Example :



                          According to :



                          dir_test
                          ├── .test
                          └── test2


                          ls dir_test : will display only test2



                          ls -A dir_test : will display test2 + .test



                          rm -r dir_test : will remove all (.test + test2)



                          I hope that will help you.






                          share|improve this answer










                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.

















                          • Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                            – marcelm
                            Sep 5 at 10:56










                          • No, ls * don't display hidden files.
                            – DevHugo
                            Sep 5 at 13:31










                          • But yes it's a little bit confused, I added some examples.
                            – DevHugo
                            Sep 5 at 13:38






                          • 1




                            ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                            – G-Man
                            2 days ago












                          up vote
                          4
                          down vote










                          up vote
                          4
                          down vote









                          If you do only ls instead of ls -a, yes rm can remove hidden files you haven't seen with ls without -a.



                          Example :



                          According to :



                          dir_test
                          ├── .test
                          └── test2


                          ls dir_test : will display only test2



                          ls -A dir_test : will display test2 + .test



                          rm -r dir_test : will remove all (.test + test2)



                          I hope that will help you.






                          share|improve this answer










                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          If you do only ls instead of ls -a, yes rm can remove hidden files you haven't seen with ls without -a.



                          Example :



                          According to :



                          dir_test
                          ├── .test
                          └── test2


                          ls dir_test : will display only test2



                          ls -A dir_test : will display test2 + .test



                          rm -r dir_test : will remove all (.test + test2)



                          I hope that will help you.







                          share|improve this answer










                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          share|improve this answer



                          share|improve this answer








                          edited 2 days ago





















                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          answered Sep 5 at 9:29









                          DevHugo

                          879




                          879




                          New contributor




                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.





                          New contributor





                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.






                          DevHugo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.











                          • Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                            – marcelm
                            Sep 5 at 10:56










                          • No, ls * don't display hidden files.
                            – DevHugo
                            Sep 5 at 13:31










                          • But yes it's a little bit confused, I added some examples.
                            – DevHugo
                            Sep 5 at 13:38






                          • 1




                            ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                            – G-Man
                            2 days ago
















                          • Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                            – marcelm
                            Sep 5 at 10:56










                          • No, ls * don't display hidden files.
                            – DevHugo
                            Sep 5 at 13:31










                          • But yes it's a little bit confused, I added some examples.
                            – DevHugo
                            Sep 5 at 13:38






                          • 1




                            ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                            – G-Man
                            2 days ago















                          Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                          – marcelm
                          Sep 5 at 10:56




                          Can you provide an example? Because normally, rm * won't remove dotfiles. If it does, ls * will also show them.
                          – marcelm
                          Sep 5 at 10:56












                          No, ls * don't display hidden files.
                          – DevHugo
                          Sep 5 at 13:31




                          No, ls * don't display hidden files.
                          – DevHugo
                          Sep 5 at 13:31












                          But yes it's a little bit confused, I added some examples.
                          – DevHugo
                          Sep 5 at 13:38




                          But yes it's a little bit confused, I added some examples.
                          – DevHugo
                          Sep 5 at 13:38




                          1




                          1




                          ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                          – G-Man
                          2 days ago




                          ls -a will list ., .., .test and test2.  You might want to change your example to use ls -A, which list everything except . and .. (i.e., only .test and test2).
                          – G-Man
                          2 days ago










                          up vote
                          3
                          down vote













                          There are already many good answers, but I want to add some more deep insight.



                          Ask yourself the question: How many parameters are passed to ls, if you write



                          ls *


                          ...? Note that the ls command does not get the * as parameter if there are any files that * can be expanded to. Instead, the shell first performs globbing before invoking the command, so the ls command actually gets as many parameters as there are files matched by the globbing. To suppress globbing, quote the parameter.



                          This is true for any command: echo * vs echo '*'.



                          There is a script, call it countparams.sh to test the effect. It tells you how many parameters it got passed and lists them.



                          #!/bin/bash
                          echo "This script was given $# parameters."
                          arr=( "$@" )
                          for ((i=0;i<$#;i++)); do
                          echo "Parameter $((i+1)): $arr[$i]"
                          done


                          Make it executable and run ./countparams.sh *. Learn from its output!






                          share|improve this answer


























                            up vote
                            3
                            down vote













                            There are already many good answers, but I want to add some more deep insight.



                            Ask yourself the question: How many parameters are passed to ls, if you write



                            ls *


                            ...? Note that the ls command does not get the * as parameter if there are any files that * can be expanded to. Instead, the shell first performs globbing before invoking the command, so the ls command actually gets as many parameters as there are files matched by the globbing. To suppress globbing, quote the parameter.



                            This is true for any command: echo * vs echo '*'.



                            There is a script, call it countparams.sh to test the effect. It tells you how many parameters it got passed and lists them.



                            #!/bin/bash
                            echo "This script was given $# parameters."
                            arr=( "$@" )
                            for ((i=0;i<$#;i++)); do
                            echo "Parameter $((i+1)): $arr[$i]"
                            done


                            Make it executable and run ./countparams.sh *. Learn from its output!






                            share|improve this answer
























                              up vote
                              3
                              down vote










                              up vote
                              3
                              down vote









                              There are already many good answers, but I want to add some more deep insight.



                              Ask yourself the question: How many parameters are passed to ls, if you write



                              ls *


                              ...? Note that the ls command does not get the * as parameter if there are any files that * can be expanded to. Instead, the shell first performs globbing before invoking the command, so the ls command actually gets as many parameters as there are files matched by the globbing. To suppress globbing, quote the parameter.



                              This is true for any command: echo * vs echo '*'.



                              There is a script, call it countparams.sh to test the effect. It tells you how many parameters it got passed and lists them.



                              #!/bin/bash
                              echo "This script was given $# parameters."
                              arr=( "$@" )
                              for ((i=0;i<$#;i++)); do
                              echo "Parameter $((i+1)): $arr[$i]"
                              done


                              Make it executable and run ./countparams.sh *. Learn from its output!






                              share|improve this answer














                              There are already many good answers, but I want to add some more deep insight.



                              Ask yourself the question: How many parameters are passed to ls, if you write



                              ls *


                              ...? Note that the ls command does not get the * as parameter if there are any files that * can be expanded to. Instead, the shell first performs globbing before invoking the command, so the ls command actually gets as many parameters as there are files matched by the globbing. To suppress globbing, quote the parameter.



                              This is true for any command: echo * vs echo '*'.



                              There is a script, call it countparams.sh to test the effect. It tells you how many parameters it got passed and lists them.



                              #!/bin/bash
                              echo "This script was given $# parameters."
                              arr=( "$@" )
                              for ((i=0;i<$#;i++)); do
                              echo "Parameter $((i+1)): $arr[$i]"
                              done


                              Make it executable and run ./countparams.sh *. Learn from its output!







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Sep 6 at 10:21

























                              answered Sep 6 at 8:26









                              rexkogitans

                              1815




                              1815




















                                  up vote
                                  1
                                  down vote













                                  The glob will expand the same way both times, if the directory contents are the same at those two different times.




                                  If you really want to check what will be removed, use rm -i *.txt. It will prompt you separately for each file before (trying to) remove it.



                                  This is guaranteed to be safe against race conditions:

                                          ls *.txt / a new file is created / rm *.txt

                                  because you're prompted for every file by the same program that's doing the removal.




                                  This is too cumbersome for normal use, and if you alias rm to rm -i, you'll find yourself using rm or rm -f fairly often. But it is worth at least mentioning that there is a solution to the race condition. (It's even portable to non-GNU systems: POSIX rm(1) specifies the -i option.)



                                  Another option would be a bash array: to_remove=(*.txt), then ask the user to confirm (perhaps after doing ls -ld -- "$to_remove[@]"), then
                                  rm -- "$to_remove[@]". So glob expansion is only done once, and the list is passed verbatim to rm.



                                  Another practically-usable option is GNU rm -I (man page), which prompts if removing more than 4 items. (But doesn't show you the list, just the total.) I use alias rm='rm -I' on my desktop.



                                  It's a nice safeguard against fat-fingering return with a half-typed pattern that matches too much. But using ls first is generally good in a directory you own, or on a single-user system, and when there aren't background processes that could asynchronously create new files there. To guard against fat-fingering, don't type rm -rf /foo/bar/baz from left to right. rm -rf / is special-cased, but rm -rf /usr isn't!  Leave out the -rf part, or start with ls, and only add the rm -rf part after typing the path.






                                  share|improve this answer


























                                    up vote
                                    1
                                    down vote













                                    The glob will expand the same way both times, if the directory contents are the same at those two different times.




                                    If you really want to check what will be removed, use rm -i *.txt. It will prompt you separately for each file before (trying to) remove it.



                                    This is guaranteed to be safe against race conditions:

                                            ls *.txt / a new file is created / rm *.txt

                                    because you're prompted for every file by the same program that's doing the removal.




                                    This is too cumbersome for normal use, and if you alias rm to rm -i, you'll find yourself using rm or rm -f fairly often. But it is worth at least mentioning that there is a solution to the race condition. (It's even portable to non-GNU systems: POSIX rm(1) specifies the -i option.)



                                    Another option would be a bash array: to_remove=(*.txt), then ask the user to confirm (perhaps after doing ls -ld -- "$to_remove[@]"), then
                                    rm -- "$to_remove[@]". So glob expansion is only done once, and the list is passed verbatim to rm.



                                    Another practically-usable option is GNU rm -I (man page), which prompts if removing more than 4 items. (But doesn't show you the list, just the total.) I use alias rm='rm -I' on my desktop.



                                    It's a nice safeguard against fat-fingering return with a half-typed pattern that matches too much. But using ls first is generally good in a directory you own, or on a single-user system, and when there aren't background processes that could asynchronously create new files there. To guard against fat-fingering, don't type rm -rf /foo/bar/baz from left to right. rm -rf / is special-cased, but rm -rf /usr isn't!  Leave out the -rf part, or start with ls, and only add the rm -rf part after typing the path.






                                    share|improve this answer
























                                      up vote
                                      1
                                      down vote










                                      up vote
                                      1
                                      down vote









                                      The glob will expand the same way both times, if the directory contents are the same at those two different times.




                                      If you really want to check what will be removed, use rm -i *.txt. It will prompt you separately for each file before (trying to) remove it.



                                      This is guaranteed to be safe against race conditions:

                                              ls *.txt / a new file is created / rm *.txt

                                      because you're prompted for every file by the same program that's doing the removal.




                                      This is too cumbersome for normal use, and if you alias rm to rm -i, you'll find yourself using rm or rm -f fairly often. But it is worth at least mentioning that there is a solution to the race condition. (It's even portable to non-GNU systems: POSIX rm(1) specifies the -i option.)



                                      Another option would be a bash array: to_remove=(*.txt), then ask the user to confirm (perhaps after doing ls -ld -- "$to_remove[@]"), then
                                      rm -- "$to_remove[@]". So glob expansion is only done once, and the list is passed verbatim to rm.



                                      Another practically-usable option is GNU rm -I (man page), which prompts if removing more than 4 items. (But doesn't show you the list, just the total.) I use alias rm='rm -I' on my desktop.



                                      It's a nice safeguard against fat-fingering return with a half-typed pattern that matches too much. But using ls first is generally good in a directory you own, or on a single-user system, and when there aren't background processes that could asynchronously create new files there. To guard against fat-fingering, don't type rm -rf /foo/bar/baz from left to right. rm -rf / is special-cased, but rm -rf /usr isn't!  Leave out the -rf part, or start with ls, and only add the rm -rf part after typing the path.






                                      share|improve this answer














                                      The glob will expand the same way both times, if the directory contents are the same at those two different times.




                                      If you really want to check what will be removed, use rm -i *.txt. It will prompt you separately for each file before (trying to) remove it.



                                      This is guaranteed to be safe against race conditions:

                                              ls *.txt / a new file is created / rm *.txt

                                      because you're prompted for every file by the same program that's doing the removal.




                                      This is too cumbersome for normal use, and if you alias rm to rm -i, you'll find yourself using rm or rm -f fairly often. But it is worth at least mentioning that there is a solution to the race condition. (It's even portable to non-GNU systems: POSIX rm(1) specifies the -i option.)



                                      Another option would be a bash array: to_remove=(*.txt), then ask the user to confirm (perhaps after doing ls -ld -- "$to_remove[@]"), then
                                      rm -- "$to_remove[@]". So glob expansion is only done once, and the list is passed verbatim to rm.



                                      Another practically-usable option is GNU rm -I (man page), which prompts if removing more than 4 items. (But doesn't show you the list, just the total.) I use alias rm='rm -I' on my desktop.



                                      It's a nice safeguard against fat-fingering return with a half-typed pattern that matches too much. But using ls first is generally good in a directory you own, or on a single-user system, and when there aren't background processes that could asynchronously create new files there. To guard against fat-fingering, don't type rm -rf /foo/bar/baz from left to right. rm -rf / is special-cased, but rm -rf /usr isn't!  Leave out the -rf part, or start with ls, and only add the rm -rf part after typing the path.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 2 days ago









                                      G-Man

                                      391310




                                      391310










                                      answered Sep 7 at 20:22









                                      Peter Cordes

                                      811713




                                      811713



























                                           

                                          draft saved


                                          draft discarded















































                                           


                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1072300%2fwill-ls-always-list-the-files-that-rm-will-remove%23new-answer', 'question_page');

                                          );

                                          Post as a guest













































































                                          Comments

                                          Popular posts from this blog

                                          What does second last employer means? [closed]

                                          List of Gilmore Girls characters

                                          Confectionery