Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • Did you write it or did Claude code slopcoded it for you? Claude is the contributor to all your other repositories. There is a world of difference between "here's a problem that I'm really concerned with and poured all my expertise to solve it" and "I told Claude to fix it for me and now I'm gonna abandon it as soon as I'm done with the HN advertising".
  • > There is a world of difference between "here's a problem that I'm really concerned with and poured all my expertise to solve it" and "I told Claude to fix it for me and now I'm gonna abandon it as soon as I'm done with the HN advertising"

    https://en.wikipedia.org/wiki/False_dilemma

  • One thing with classical UNIX commands, is that you can expect to find them into random computers besides one's own laptop.

    Not everyone has the luxury to only work with their own computer, or run random software on IT/customer managed systems.

  • This is why I tend to stick to POSIX shell scripting these days, avoiding even bash. The restriction does make some things too painful, though. Before the latest POSIX revision, certain workflows were comically hard to do (unless you combine sh with... M4). The 2024 revision injects some much-needed sanity, but I am wondering, will random computers have shells compliant with that revision?
  •   find -print0 | xargs -0 -I {} "the {} iterated command"
    by ggm
  • why would you ever pipe find into xargs instead of calling -exec?

        find -exec the '{}' iterated command ';'
  • And for most of those commands add a dash dash so that nothing with a dash prefix turns into options.
  • Xargs is fine, but openbsd has a -J option and every time I read the man page to figure out how to use it I read the -I and -J options and my brain glazes over.

    https://man.openbsd.org/xargs

    Other brain glazing obsd wierdness is it's two argument cd command, a cryptid I am unable to wrap my head around.

    https://man.openbsd.org/ksh#cd~2

  • On the topic of xargs replacements, I love gnu parallel.

    The --dry-run flag of parallel made me confident to do more batch processing than I ever did with xargs.

    Parallel has an option for almost everything, it's almost too much.

    But I have shopped around for alternatives. The creator Ole Tange maintains a painstakingly long article of the alternatives and their differences. [0]

    The gnu parallel book and reading materials [1] are excellent too.

    [0] https://www.gnu.org/software/parallel/parallel_alternatives....

    [1] https://www.gnu.org/software/parallel/#Tutorial

  • Parallel is ok but rush is nicer and much faster.

    https://github.com/shenwei356/rush

  • isn't parallel that tool that dumps some kind of begging message into your output each time you invoke it?
  • I love GNU Parallel too. I love how it's free software and how I can patch out the obnoxious citation notice.
  • Every time I’ve used Gnu Parallel on a new system it required accepting a Eula, which is annoying. I stick to xargs -P99 these days and am happier.

    Utility software which has non-essential different first-run behavior is hostile to users.

  • Oh man, parallel is awful. I have to rant about this because I literally tried it again today morning.

    Every single damn time I try parallel and decide to give it another chance, something ends up not working or causing a problem. I can never get it to just do what I want and get out of the way.

    Today I foolishly thought maybe I was the one who was holding it wrong every single time in the past, so I copy pasted another command that was supposed to work, and thought surely this would be straightforward. Boy was I wrong. I got some manifesto about academic citations and plagiarism, which confused the hell out of me. After I wasted time trying to figure out how to turn off that nonsense, the app just hung there trying to figure out how long its command line can be? Literally doing nothing? What the hell? I killed it but then my terminal didn't close because every time I did this apparently some perl command was spawned in the background blocked on nothing. Why the hell was perl even relevant? Nothing I wrote used Perl. Just run the darn commands I asked in parallel, is that so hard?

  • I have used echo as a sort of poor mans equivalent for a safe check of a pipeline, removing the echo when I felt the rest of the pipeline was working correctly.

      shell stuff | xargs -n 1 -I % echo real command and % args
    
    I have also been known to write scripts where instead of executing the critical parts it prints them. Then a dry run is

      script
    
    and the real run is

      script | sh
  • I wanted something simpler — one consistent way to iterate over anything.

    That's not actually simpler though. Simple is removing everything unnecessary. You took commands which could already do what you wanted, and added an extra program which calls them in specific ways. This will add bugs and maintenance headaches, not be portable, etc. This is added complexity.

    The reason you made this script is not because you wanted simpler, you wanted easier. There's nothing wrong with that, and I'll grant you it probably is, especially for those unaccustomed to these commands. But easier != simpler. Often you'll find that simple is hard and easy is complexity deferred.

  • Hm. Underrated comment
  • > Or maybe you pipe into xargs and pray your filenames don’t have spaces…

    Always use -0. Most gnu utilities support it. It makes them put a null byte after every filename instead of a newline. Completely eliminates the problem of dealing with whitespace in the filenames.

  • For tools that don't support -0, you can add the NULs yourself without much fuss. It's a one-liner in awk/perl/sed. Very handy.
  • No dependency on GNU required anymore, POSIX 2024 supports it: https://blog.toast.cafe/posix2024-xcu#the-null-option
  • To support your recommendation and redress the strawman the article postulates, the post's author could have replaced:

      find . -name '*.log' | xargs rm
    
    With:

      find . -name '*.log' -print0 | xargs -0 rm
  • If you want a shell to interact with the results, you can of course just use a (sub)shell.

        ls -1 ./*.sh | xargs -rd\\n sh -c 'for i in "$@" ; do ... ; done' sh
    
    1. not strictly necessary to use -1 as I believe all common ls detect !isatty(stdout) and produce line-by-line output anyway.

    2. xargs -r just doesn't run the command if there's no input, also not strictly necessary but I'm addicted to using it because it's the sensible default to me.

    3. xargs -d\\n makes it collect fields as full lines, which is what you typically want, unless you're able to generate NULs.

    4. use whatever shell you want of course, but I don't use bashisms, etc., by default, /bin/sh is fine for me, even if it's dash.

    5. the trailing "sh" at the end is due to a quirk of `sh -c` usage, where $0 is the first non option argument, so `printf %s\\n 1 2 3 | xargs -rd\\n sh -c 'for i in "$@" ; do printf "%s " "$i" ; done ; echo'` (note the lack of trailing "sh") would only print "2 3 " as $0 is not included in "$@" ($0 is 1, $1 is 2, $2 is 3). It's very easy to just always give the shell name itself manually as $0 instead of trying to ingest "$0" into your logic.

    Of course, you could `find . -maxdepth 1 -type f -name '*.sh' -print0 | xargs -r0 ...` instead, depending on what you're up to, that may be the easiest. It's definitely the simplest -- as long as your xargs has -0 support.

  • > not strictly necessary to use -1 as I believe all common ls detect !isatty(stdout)

    I remember, though from the dim an distant past so it could be a long-fixed bug, this not working in at least one circumstance. I've explicitly included -1 in scripted calls to ls since. Of course we are breaking the best practice rule of not trying to parse the output of ls, so problems are not unexpected…

    As a generally thing I like to include directives like this in scripted calls even if they happen by default anyway, because is makes my intent clear: I expect the output to being in simple single-column format and the rest will break if it isn't. I even sometimes go as far as specifying --sort=name if nothing else in the pipeline is going to enforce that.

    > as long as your xargs has -0 support

    I don't think I've encountered an xargs that doesn't have this support for a long time, though I don't work with embedded stuff so maybe there are cut-down versions out there still in active use for space reasons.

    The problem I've hit numerous times is wanting to do something between “find -print0” and “xargs -0” and that something not supporting NUL as the item delimiter.

  • In this thread: bash experts with arcane knowledge, unintentionally demonstrating how awful bash is.

    The obvious solution would be to use something more sane, like PowerShell or nushell, but instead old experts will always defend the skills they have honed for years, while criticizing anything that's different.

  • I always avoid Bash

    I prefer Almquist (ash), eg., NetBSD sh, Debian sh with tab completion, busybox ash, etc.

    Powershell must be slow and/or bloated like Bash; someone wrote xargs in C++ for Windows:

    https://github.com/idigdoug/TextTools/tree/main/wargs

  • This is a sleeper option, but 'xonsh' as a Python superset is a very pleasant experience, especially when you just don't feel like learning another bespoke language for the complex stuff.

    I once had to scrape the output out of something hacked together by a grad student 10 years before me, scrape yet another hacked together application, do some fancy numerics, and then plonk it into a database. I did it without tears!

  • No, there are two problems here:

    1. Things have developed over time. Bash and other shells weren't always this way. If you have ever touched different shells, awk, sed and so on and then touch perl you see how it is basically just the glue between the other tools put into one language.

    2. The majority of scripts is written in sh or bash. So these shells won't go away anytime soon and any newcomer will be confronted with them. So it's best to know all the edge cases before you do stuff you don't want to do. And yes, you could always install another shell. But that brings another dependency and opens up another can of worms. In professional environments it's not really an option to have the next exotic language.

    It's like having a tmux.conf on your local machine that configures tmux exactly the way you want it. Nice to have but the moment you touch any of the other billions of systems out there that run the default configuration, you might be lost because you never learned the default and only use your modified version.

  • Yes, Bash is filled with footguns and is awful due to that. However, it's still incredibly useful as it's everywhere and has a far greater lifespan than almost anything else. You can write scripts in PowerShell or nushell, but then find that twenty years later they're no longer usable or you find a twenty year old machine that won't have PowerShell/nushell installed.

    It's not so much about defending arcane scripting skills, but that Bash functions as a lowest common denominator and is useful because of that. If you want something that works reliably over decades, then it's best not to go for an "improved" shell as it may not still be around.

    I like to think of Bash script writing as the opposite of riding a bike - you have to relearn it almost every time you write a script.

  • Maybe it is out of habit, but I never managed to get into PowerShell, in fact, I am not at easy with the Microsoft way of doing things, with few exceptions. Too much UNIX I guess. Nushell seems to be based on the PowerShell philosophy of using structured data and not text, not my thing.

    I really like the UNIX way of using text I/O, it has it flaws but it works for me. But that being said, I still hate bash and all its family. It has so many footguns it is an entire armory at this point, mostly related to spaces and escaping.

    Something Perl-like could be a saner replacement. It is already a bit shell-like, it doesn't struggle with escaping the way bash does, and it has very powerful text processing abilities that go well with traditional UNIX tools.