1. 20
  1.  

  2. 15

    He didn’t mention the -a and -o short circuiting logical and/or operators, along with !, \( and \), which I think are both the most confusing and most powerful part of find.

    It helps to think of it as boolean expression language with no lexer – the argv array are the tokens, so the lexer is the shell in some sense. That is why you need all this weird shell quoting.

    The -a is implicit which is why a lot of people are confused about this. Also -a print is implicit in many commands.

    find . -type f -name "*.css"
    

    is equivalent to:

    find . -type f -a -name "*.css" -a -print
    

    Or if you want a better imaginary syntax, you could do:

    find . (type == 'f' && name ~ '*.css' && print)
    

    And it’s not lost on me that this looks like Awk… Awk is a predicate/action language over lines. Find is a predicate/action language over file system metadata. They just have vastly different syntax.

    UPDATE: The action language for find consists of -print, -printf, -exec, -rm, and the sequencing operator \;. -print is really short for -printf %p. It’s weird that the actions look like flags.

    1. 1

      As a small note; the \ is just to escape shell sequences. Alternatively, one could put the arguments entirely into one large string surrounded by double or single quotes, removing the need to escape them.

      Secondly, with gnu find, there is an alternative to \; which is + and much more efficient. The former executes a cmd for each result, the latter for as many results as the allowed cmd length. So with 30 results and -exec ls {} \;, ls is executed 30 times. With -exec ls {} +, ls is executed just one.

      1. 2

        Well you have to do something like:

        find . ‘(’ -type f ‘)’ -a -exec echo hi ‘;’ -exec echo bye ‘;’

        You can’t put the whole expression in one large single or double quoted string. They have to be separate args.

        Yes I found out about ‘+’ this year. However I tend to use find -print0 | xargs -0 because you can use -P. Bundling that functionality in find is sort of a cat -v orthogonality problem. xargs is already supposed to execute processes so find shouldn’t need that.

        In fact the author of the lr tool mentioned on this page also has that pet peeve.

    2. 12

      find is my favorite tool. I use it constantly, and am always amazed when my coworkers think it at all mystical or magical that I know how to use it. Ten minutes spent in it’s man page will leave you well equipped to use it in a basic sense, and it is easily one of the best tools for traipsing through a system rapidly and precisely. I encourage everyone to learn it, it’s pretty ubiquitous, and just so very useful.

      1. 5

        Nitpick unrelated to the actual content: every technical post should have the publication date visible on the page. This one is from 2008, according to https://www.eriwen.com/archives/.

        This post is still relevant, but the comparison to “Google Desktop” was a little jarring when I thought it was a new post.

        Dates are really needed if you write about tech that changes quickly. Versions would be nice in that case, too.

        1. 3

          One thing I wish Unix people would stop doing is ignoring the existence of PowerShell on Windows. I get that this guy is talking about find in particular, but I challenge shell aficionados to at least look at it, rather than state that Cygwin (which is rather painful to use especially at first) is the only way to get a real shell on Windows.

          My first time I definitely saved time as a programmer was in Power Shell was for a very find style use case, specifically for finding a .docx that my brother had misplaced. Like awk on *nixen, PowerShell is a language you have access to on every Windows computer since Windows 7. If you’re going to be bring up shells on Windows, it’s very worth a look.

          1. 3

            my problem with PowerShell is it’s always locked down so I cannot use it productively, that, double clicking, and no middle button pasting means Windows is just a frustration to use, for me :~(

            1. 4

              Yeah, Windows still needs to work on its out of the box console experience. If you own or have admin on the machine that you’re using PowerShell on you should be able to unlock it via Set-ExecutionPolicy. I usually see advice for RemoteSigned.

              What do you mean about the double clicking?

              For what it’s worth, it’s worth installing ConEmu if you haven’t already and if you’re going to be on a Windows machine for more than a few hours. It allows for a lot of the terminal conveniences that you get on OSX/Linux, regardless of what shell you run in it.

            2. 1

              I have used PowerShell on a few occasions but still very much prefer the Bash that comes with the Portable Git install on Windows. Although Bash might not be the best shell, which I don’t have any opinion about, it is quite usable, having sensible tab completion and history support. In addition, PowerShell often requires you to write multi line scripts for tasks that are easily achieved by a one-liner in bash.

              1. 4

                I also default to Bash that comes with the Portable git install on Windows. I suppose I have two major complaints:

                1. Dismissing PowerShell out of hand, without at least acknowledging it. PowerShell is an enormously useful tool when you’re on Windows and you need to interact with Windows things. It’s quite passable for regular shell stuff as well.
                2. Suggesting Cygwin to as “the real shell”, rather than any of a bunch of much easier to use options, Git Bash, PowerShell, and/or the Bash subsystem for Windows being some of them. Cygwin is just about the most painful way to set up a shell on Windows, only to be used if you have to get something that refuses to work on Windows otherwise.

                I suspect that the one-liner/mulitiline dichotomy is mostly around things where bash has utils aimed at a given pain point, where PowerShell may not at this point. That being said, PowerShell has been advanced a lot over time. PowerShell 1.0 in Windows 7 is far less mature than PowerShell 3.0 on Windows 8.1 or 10. Also, with the proper path setup, one can use those utils in PowerShell if you wanted to.

                I tend to interact with Bash, and use PowerShell for things that interact with .NET or Windows Scheduled tasks.

                1. 1

                  Dismissing PowerShell out of hand, without at least acknowledging it.

                  I think that for a lot of people, the advantage of Bourne shells + basic UNIX utilities is that it is available on any Unix-like system. Although Powershell has been ported to other platforms, it requires a fairly large .NET runtime that people do not want to install on servers (AFAIK Mono AOT is still pretty limited in platform support).

                  As a result, Powershell is pretty much confined to Windows.

                  1. 1

                    PowerShell’s cross platform story is weak, and mostly Windows Centric. But so was the author’s Cygwin comment.

              2. 1

                PowerShell doesn’t really feel like a shell in the sense of being designed for interactive use. It may well be a fine programming language, but it’s just too verbose to use as an actual shell, IME.

                1. 1

                  PowerShell’s aliases help bridge that gap, in my experience.