• Removing empty directories

    From Janis Papanagnou@21:1/5 to All on Mon Jun 13 11:43:31 2022
    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects. So I was looking for some test based
    approach like [[...]] && rmdir "$dir" but couldn't find simple
    tests for that (e.g. -d and link count comparison isn't really
    elegant either, the same with something like ls .* * 2>/dev/null
    and string comparisons, or similar).

    The rmdir(1) command is delegated to the rmdir(2) system call.
    What would rmdir(2) do to determine the emptiness? Would we
    have to do something similar/complex or am I missing something
    obvious?

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From marrgol@21:1/5 to Janis Papanagnou on Mon Jun 13 14:08:47 2022
    On 13/06/2022 at 11.43, Janis Papanagnou wrote:
    Is there some elegant way to test/remove an empty directory?

    I use 'find' for this. E.g. assuming $dir is just a name, not a path,
    and it is in current directory:

    $ find . -maxdepth 1 -type d -name "$dir" -empty -delete

    I usually skip '-maxdepth 1' to also delete all empty sub-directories
    of $dir.


    --
    mrg

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to janis_papanagnou@hotmail.com on Mon Jun 13 12:44:42 2022
    In article <t870s4$118f$1@gioia.aioe.org>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    Is there some elegant way to test/remove an empty directory?

    I assume that the basic answer to your question is going to be: NO.

    I.e., I assume you are familiar with and, more importantly, entirely
    capable of working out on your own any/all of the available kludgey workarounds. Another user has given a kludgey workaround using "find".

    Keep in mind that any version of the form "test/find an empty directory,
    then remove it" could fail due to the "race condition" - i.e., whatever
    that fancy acronym is for "time of test/time of use".

    FWIW, here is an idea that I have used in some of my scripts, where there
    is one error message that you anticipate (and which, therefore, is not
    really an error), but you still want to capture any other (unexpected)
    error messages:

    someCommand 2>&1 | grep -v "Expected Error Message"

    Nitpickers note: Note that this ignores "errorlevel"; some polish may be
    needed to get the errorlevel to come out right. The bash option "pipefail"
    may be useful here...

    --
    You are again heaping damnation upon your own head by your statements.

    - Rick C Hodgin -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Collver@21:1/5 to Janis Papanagnou on Mon Jun 13 12:35:44 2022
    On 2022-06-13, Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects. So I was looking for some test based
    approach like [[...]] && rmdir "$dir" but couldn't find simple
    tests for that (e.g. -d and link count comparison isn't really
    elegant either, the same with something like ls .* * 2>/dev/null
    and string comparisons, or similar).

    The rmdir(1) command is delegated to the rmdir(2) system call.
    What would rmdir(2) do to determine the emptiness? Would we
    have to do something similar/complex or am I missing something
    obvious?

    Janis

    Here's an idea for bash:

    (shopt -s dotglob; cd dir; if [ -z "$(ls)" ]; then \
    echo empty; else echo full; fi)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Janis Papanagnou on Mon Jun 13 12:50:00 2022
    On 2022-06-13, Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    The rmdir(1) command is delegated to the rmdir(2) system call.
    What would rmdir(2) do to determine the emptiness?

    I believe rmdir must be a dedicated primitive in each filesystem implementation, including checking the necessary criteria.

    The rmdir implementation in a sufficiently Unix-like filesystem can just
    look at the link count: an empty (non-root) directory has a link count
    of exactly two: one is the "." self link, and the other is its name in
    the parent (the thing being deleted).

    Would we
    have to do something similar/complex or am I missing something
    obvious?

    GNU find has an -empty directive. This actually opens the directory,
    and reads it until it finds an entry which is neither "." nor "..".
    I suspect that is the only way which approaches 100% portability across filesystems.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Janis Papanagnou on Mon Jun 13 13:58:43 2022
    Janis Papanagnou <janis_papanagnou@hotmail.com> writes:

    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects.

    Depending on what rmdir you have, and what your portability requirements
    are, you might find that

    rmdir --ignore-fail-on-non-empty "$dir"

    does what you want.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Christian Weisgerber on Mon Jun 13 15:05:37 2022
    On 2022-06-13, Christian Weisgerber <naddy@mips.inka.de> wrote:
    On 2022-06-13, Kaz Kylheku <480-992-1380@kylheku.com> wrote:

    The rmdir implementation in a sufficiently Unix-like filesystem can just
    look at the link count: an empty (non-root) directory has a link count
    of exactly two: one is the "." self link, and the other is its name in
    the parent (the thing being deleted).

    I seemed to remember something like that, but a quick check shows
    that a directory's link count is two plus the number of direct subdirectories.

    Other contents, such as files, fifos or symlinks,
    are not reflected in the link count.

    You're right; what was I thinking?

    Of something else: namely that the directory link count is only
    useful for knowing whether there are subdirectories, which is useful
    for optimizing a recursive descent, in the case when you're only
    looking for subdirectories.

    Interestingly, GNU find doesn't take advantage of this; it is still
    reading directory entries of "dir" when invoked as "find . -type d dir",
    where dir has no children, even though it has done the stat call on it informing it of the link count of 2.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Kaz Kylheku on Mon Jun 13 13:42:10 2022
    On 2022-06-13, Kaz Kylheku <480-992-1380@kylheku.com> wrote:

    The rmdir implementation in a sufficiently Unix-like filesystem can just
    look at the link count: an empty (non-root) directory has a link count
    of exactly two: one is the "." self link, and the other is its name in
    the parent (the thing being deleted).

    I seemed to remember something like that, but a quick check shows
    that a directory's link count is two plus the number of direct
    subdirectories. Other contents, such as files, fifos or symlinks,
    are not reflected in the link count.

    --
    Christian "naddy" Weisgerber naddy@mips.inka.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Kaz Kylheku on Mon Jun 13 22:24:35 2022
    On 2022-06-13, Kaz Kylheku <480-992-1380@kylheku.com> wrote:

    Of something else: namely that the directory link count is only
    useful for knowing whether there are subdirectories, which is useful
    for optimizing a recursive descent, in the case when you're only
    looking for subdirectories.

    This also reminds me of something... ah, this caveat in GNU find's
    man page:

    -noleaf
    Do not optimize by assuming that directories contain 2 fewer
    subdirectories than their hard link count. This option is
    needed when searching filesystems that do not follow the Unix
    directory-link convention, such as CD-ROM or MS-DOS filesystems
    or AFS volume mount points. [...]

    --
    Christian "naddy" Weisgerber naddy@mips.inka.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Helmut Waitzmann on Tue Jun 14 00:40:31 2022
    On 2022-06-13, Helmut Waitzmann <nn.throttle@xoxy.net> wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com>:
    Is there some elegant way to test/remove an empty directory?


    I'm not sure:  Does


    { test -d "$dir" && test -s "$dir" ; }

    test for an empty directory?  Then

    The -s test is documented for files. It probably checks the inode
    st_size for zero. If it happens to work for a directory also, by doing
    the same test, then that won't work because a directory is never
    literally empty.do that for directories also, it won't work because a
    directory is never literally empty.

    By the way, it's inverted: a "test -s f" success means
    that f is *not* empty.

    I tried it on some emtpy and nonempty directories; it's always
    succeeding (indicating non-empty).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Tue Jun 14 01:48:30 2022
    Janis Papanagnou <janis_papanagnou@hotmail.com>:
    Is there some elegant way to test/remove an empty directory?


    I'm not sure:  Does


    { test -d "$dir" && test -s "$dir" ; }

    test for an empty directory?  Then


    { test -d "$dir" && test -s "$dir" ; } ||
    rmdir -- "$dir"

    should do the job.  (Of course it won't solve the race condition
    problem.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Ben Bacarisse on Tue Jun 14 08:57:00 2022
    On 13.06.22 14:58, Ben Bacarisse wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com> writes:

    Is there some elegant way to test/remove an empty directory?

    First, thanks to all for the suggestions and thoughts posted!


    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects.

    Depending on what rmdir you have, and what your portability requirements are, you might find that

    rmdir --ignore-fail-on-non-empty "$dir"

    does what you want.

    This is indeed where I'd consider it best placed, as part of the
    rmdir command - similar to the mkdir command with mkdir -p option.
    (Would be nice if such an option gets standardized.) - Rethinking
    about a separate test; this is probably not that good an idea for
    my case, since I want to remove multiple directories and would want
    to use shell patterns for that, like rmdir -option <date_pattern>
    and individual tests would make a loop over the directory-list
    necessary (which is also not an issue with a 'find'-based approach).
    Currently I am using that code in a GNU context only, so I can use
    the suggested rmdir option.

    One thing I am wondering, though, is; why isn't there a short form
    of that option available? (There's plenty of free letters available
    with the rmdir command.) The thought to mistype the long option, or
    the necessity to call the man page and use the mouse to copy/paste
    the exact text is not appealing for a shell programmer (concerning
    usability).

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Aragorn@21:1/5 to All on Tue Jun 14 11:03:57 2022
    On 14.06.2022 at 08:57, Janis Papanagnou scribbled:

    One thing I am wondering, though, is; why isn't there a short form
    of that option available? (There's plenty of free letters available
    with the rmdir command.) The thought to mistype the long option, or
    the necessity to call the man page and use the mouse to copy/paste
    the exact text is not appealing for a shell programmer (concerning usability).

    Why not create an alias or a shell function for it?

    --
    With respect,
    = Aragorn =

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Aragorn on Tue Jun 14 12:22:46 2022
    On 14.06.22 11:03, Aragorn wrote:
    On 14.06.2022 at 08:57, Janis Papanagnou scribbled:

    One thing I am wondering, though, is; why isn't there a short form
    of that option available? (There's plenty of free letters available
    with the rmdir command.) The thought to mistype the long option, or
    the necessity to call the man page and use the mouse to copy/paste
    the exact text is not appealing for a shell programmer (concerning
    usability).

    Why not create an alias or a shell function for it?

    Because it's unnecessary overhead and unnecessary complexity. And
    aliases are, conceptually, an interactive feature. It's the wrong
    approach to put the burden for providing simply usable interfaces
    on the users' side - each user with her own workaround/wrapper! -
    instead of supporting a user-friendly design in the first place.
    YMMV.

    The schizophrenic thing in this case is that rmdir's other options
    -v (--verbose), -p (--parents) have short and long form definitions
    even though the long forms are rather short and easily memorizable
    but the one with a pathological length (--ignore-fail-on-non-empty,
    that's five word components!) has no short form. And I still wonder
    why, what the designers think when doing that. If I'd want users to
    *not* use a feature or option I'd certainly choose a name like that.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to janis_papanagnou@hotmail.com on Tue Jun 14 10:33:46 2022
    In article <t89nhn$1qva$1@gioia.aioe.org>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    The schizophrenic thing in this case is that rmdir's other options
    -v (--verbose), -p (--parents) have short and long form definitions
    even though the long forms are rather short and easily memorizable
    but the one with a pathological length (--ignore-fail-on-non-empty,
    that's five word components!) has no short form. And I still wonder
    why, what the designers think when doing that. If I'd want users to
    *not* use a feature or option I'd certainly choose a name like that.

    The future trend, like it or not, is towards more and more longer options, some, as here, w/o short-form equivalents. I think the general feeling
    among the developer community is that short (one letter) options are
    ambiguous and generally be avoided. They are retained mostly for
    historical compatibility.

    A good example of what can go wrong is this: For most programs, most of
    the time, "-v" means "be verbose", which means it is A) generally a good
    idea to include it, and b) safe to do so. But, in the "pkill" command,
    "-v" means (basically) kill everything. Everybody gets bit by this at some point in their careers; this is why I think pgrep/pkill should be avoided.

    It would be good to have a global, system-wide convention that "-v"
    *always* means "be verbose" - always - and that it is always safe to
    include it on the command line.

    Finally, I don't understand your reluctance to use this long option (the 5
    word one), since: A) It does exactly what you want (I was wrong to say
    there was no non-kludgey answer to your question) and B) You are writing a script, right?, it is not like you have to type that out interactively.
    Just put it in your script and be done with it.

    --
    Mike Huckabee has yet to consciously uncouple from Josh Duggar.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Elvidge@21:1/5 to Kenny McCormack on Tue Jun 14 12:33:10 2022
    On 14/06/2022 11:33, Kenny McCormack wrote:
    In article <t89nhn$1qva$1@gioia.aioe.org>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    The schizophrenic thing in this case is that rmdir's other options
    -v (--verbose), -p (--parents) have short and long form definitions
    even though the long forms are rather short and easily memorizable
    but the one with a pathological length (--ignore-fail-on-non-empty,
    that's five word components!) has no short form. And I still wonder
    why, what the designers think when doing that. If I'd want users to
    *not* use a feature or option I'd certainly choose a name like that.

    The future trend, like it or not, is towards more and more longer options, some, as here, w/o short-form equivalents. I think the general feeling
    among the developer community is that short (one letter) options are ambiguous and generally be avoided. They are retained mostly for
    historical compatibility.

    A good example of what can go wrong is this: For most programs, most of
    the time, "-v" means "be verbose", which means it is A) generally a good
    idea to include it, and b) safe to do so. But, in the "pkill" command,
    "-v" means (basically) kill everything. Everybody gets bit by this at some point in their careers; this is why I think pgrep/pkill should be avoided.

    It would be good to have a global, system-wide convention that "-v"
    *always* means "be verbose" - always - and that it is always safe to
    include it on the command line.

    Finally, I don't understand your reluctance to use this long option (the 5 word one), since: A) It does exactly what you want (I was wrong to say
    there was no non-kludgey answer to your question) and B) You are writing a script, right?, it is not like you have to type that out interactively.
    Just put it in your script and be done with it.


    Perhaps log options are the future, but I thought long options were
    those introduced by -- rather than - , not that they must be long strings.
    What would be wrong with --ifone? Or --ifine (ignore fail if not empty). -on-non-empty doesn't seem (to me) to be a reasonable language construct.

    -v always equals --verbose would be a good idea. -V always being
    --version would perhaps also be a good idea?
    Would a call to the coreutils guys be in order?


    --
    Chris Elvidge
    England

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Kenny McCormack on Tue Jun 14 15:48:18 2022
    On 2022-06-14, Kenny McCormack <gazelle@shell.xmission.com> wrote:
    In article <t89nhn$1qva$1@gioia.aioe.org>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    The schizophrenic thing in this case is that rmdir's other options
    -v (--verbose), -p (--parents) have short and long form definitions
    even though the long forms are rather short and easily memorizable
    but the one with a pathological length (--ignore-fail-on-non-empty,
    that's five word components!) has no short form. And I still wonder
    why, what the designers think when doing that. If I'd want users to
    *not* use a feature or option I'd certainly choose a name like that.

    The future trend, like it or not, is towards more and more longer options, some, as here, w/o short-form equivalents. I think the general feeling

    Maybe there use for medium-form options, you know?

    Unix has two and three-letter commands: cat, mv. That is a good
    and useful improvement over one-letter commands, and better
    than catenate-inputs or rename-or-move-objects.

    The problem with --ignore-fail-on-non-empty that it's five words
    long.

    That's as many words in one option than the number of options GNU rmdir supports!

    How about: before adding two-word options, run out of one-word options.

    Oh, and here is something: nonempty is a word, like nontoxic,
    nonnegative, nonsense. The Latin prefix non- often doesn't
    require a dash, unless it is put on a compound that itself needs
    a dash, like "non-age-related".

    among the developer community is that short (one letter) options are ambiguous and generally be avoided. They are retained mostly for
    historical compatibility.

    Or maybe utility programs that needs more than 20 options want
    either to be split into multiple utilities?

    A utility program is actually a kind of function, That's why
    we speak about arguments.

    When the argument options produce a different function,
    there is often a good case to give that a different function
    name.

    In math, a simple option such as a phase shift of 90 degrees
    producews a different name

    sin(45)

    not:

    cos(--shift=-90, 45)

    The reason this happens in programs is because there is a large
    barrier potential working against starting a new program, which has a
    lot in common with the exsiting program. It needs more effort, resources
    and inevitable duplication.

    Using the same program under different names complicates the
    installation somewhat; there has to be a step which hard links the
    thing, and then you are running into how the program can know its
    executable name in the best way under all possible circumstances, which
    runs into platform-specific coding.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Ben Bacarisse on Tue Jun 14 16:27:34 2022
    On 2022-06-13, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com> writes:

    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects.

    Depending on what rmdir you have, and what your portability requirements
    are, you might find that

    rmdir --ignore-fail-on-non-empty "$dir"

    does what you want.

    This option is next to useless; all it does is prevent an unsuccesful termination status of rmdir due to nonempty directories.

    Both these commands will have the same effect on the file system:

    rmdir empty1 empty2 nonempty empty3

    rmdir --ignore-fail-on-nonempty empty1 empty2 nonempty empty3

    the first one will have a failed termination status due to not
    having removced nonempty.

    But the refusal to remove nonempty is just a technical/historic
    limitation in the first place. It comes from, roughly this:

    1. There is a primitive system call which (for good reasons)
    is restricted to removing a directory, which is empty.
    The good reason for this is that the operation must be
    implemented multiple times for different kinds of filesystems.
    Whereas a recursive removal can be implemented in a higher
    layer, independently of filesystems.

    2. For historic reasons, the primitive system call was mirrored
    in a rmdir utility which is more or less just a wrapper
    for it (except for the -p feature it begat).

    3. The "remove anything, including recursively" functionality
    became the domain of the "rm" command, and so the
    requirements for "rmdir" have not been maintained
    in that direction.

    When I'm doing this:

    rmdir empty1 empty2 nonempty empty3

    I almost always want all four directories to just be gone.
    In other words, I want

    rm -r(f) empty1 empty2 nonempty empty3

    Now maybe if they cannot all be gone, the *ideal* behavior for
    rmdir would be to do nothing: fail and do not touch the filesystem.
    Yet, I would want that to happen for some real reason not
    because some directory is nonempty.

    The that there is a primitive rmdir operation in the kernel's VFS layer
    that doesn't work on nonempty directories is completely irrelevant to
    what I'm doing. It's annoying implementation level fluff, exactly like
    Windows refusing to delete a file that's open in some application.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Kenny McCormack on Tue Jun 14 19:56:47 2022
    On 14.06.22 12:33, Kenny McCormack wrote:
    In article <t89nhn$1qva$1@gioia.aioe.org>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    The schizophrenic thing in this case is that rmdir's other options
    -v (--verbose), -p (--parents) have short and long form definitions
    even though the long forms are rather short and easily memorizable
    but the one with a pathological length (--ignore-fail-on-non-empty,
    that's five word components!) has no short form. And I still wonder
    why, what the designers think when doing that. If I'd want users to
    *not* use a feature or option I'd certainly choose a name like that.

    The future trend, like it or not, is towards more and more longer
    options,
    some, as here, w/o short-form equivalents. I think the general feeling among the developer community is that short (one letter) options are ambiguous and generally be avoided. They are retained mostly for
    historical compatibility.

    There's nothing wrong in supporting long options [in addition to the
    short ones]. It's sort of a in-code documentation that we observe in
    many programming languages (Java comes to mind, specifically), mainly
    where [arbitrary] user entities are introduced; variables, functions,
    classes, packages, etc. In such languages we have IDEs that provide
    us with the feature to get lists of names we can simply choose from,
    though, we don't look them up or type them any more.

    Unix commands are not quite comparable, since it's a toolbox, more
    like (but not exactly) the underlying operating language. It has at
    least a stability factor (as opposed to user defined entities), as
    we can derive from the long time standardization efforts.

    My question about the "Why?" - which, frankly, isn't addressed by
    pointing to a "future trend" - stems from practical considerations,
    how shell programs are regularly developed and used. The whole mess
    could probably be best described by a (fictional) command like this:
    list-filesystem-item --display-in-long-format --sort-by-time \
    --order-is-oldest-first
    in case it's not obvious, this is something like the commonly used
    'ls -ltr', and it resembles more the commands of a TR 440 computer
    from the mid of the last century than anything modern (and even the
    TR 440 operating system allowed command abbreviations, if I recall
    correctly; i.e. the "trend" at that time was to make things usable).


    A good example of what can go wrong is this: For most programs, most of
    the time, "-v" means "be verbose", which means it is A) generally a good idea to include it, and b) safe to do so. But, in the "pkill" command,
    "-v" means (basically) kill everything. Everybody gets bit by this
    at some
    point in their careers; this is why I think pgrep/pkill should be
    avoided.

    I completely agree that the choice of option names is not (or rather
    can not be) coherent across the many existing Unix tools. But that's
    another point, and the question is; what to do design-wise to address legibility - ideally without sacrificing the advantages of short form
    options. The path taken was the introduction of long options; and to
    repeat myself, that's a good thing. (But doesn't adress the question
    why there's no short option.)


    It would be good to have a global, system-wide convention that "-v"
    *always* means "be verbose" - always - and that it is always safe to
    include it on the command line.

    For a subset of common options that would be good, I agree. (But that's
    again independent of introducing long option names.)

    There's also other, additional possibilities to address the flood of (different) option names. We could avoid defining specific functions
    by options; 'ls' or 'ps' comes to my mind. We could replace options
    that are only defining (output-)format by format options (AIX's ps -o
    as an example), which has meanwhile found its way into some commands.


    Finally, I don't understand your reluctance to use this long option
    (the 5
    word one), since: A) It does exactly what you want (I was wrong to say
    there was no non-kludgey answer to your question) and B) You are
    writing a
    script, right?, it is not like you have to type that out interactively.
    Just put it in your script and be done with it.

    I was looking for an "elegant" solution. My reluctance stems from the
    fact that a programmed [kludgy] workaround (using even perl, awk, sh one-liners) would not be larger (character-count-wise) than the length
    of that option name.

    Yes, I can copy/paste that option-"sentence" and put that in my script.
    But I think it is nonetheless a valid question I asked; why there's
    no short form available. (And why "trendy" designers do what they've
    done, since there's yet a rationale missing why they are thinking that
    the 1950's way of OS-language design would be sensible in this case.)

    For my day-to-day use of the shell language I don't want to look up
    whether the option was "--order-is-oldest-first", "--oldest-first", "--order-by-oldest-first", or whatever; I clearly prefer '-t' when
    typing the 'list-filesystem-item', erm.., the 'ls' command.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Tue Jun 14 22:51:12 2022
    Kaz Kylheku <480-992-1380@kylheku.com>:
    On 2022-06-13, Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:

    The rmdir(1) command is delegated to the rmdir(2) system call.
    What would rmdir(2) do to determine the emptiness?

    I believe rmdir must be a dedicated primitive in each filesystem >implementation, including checking the necessary criteria.

    […]

    Would we have to do something similar/complex or am I missing
    something obvious?

    GNU find has an -empty directive. This actually opens the
    directory, and reads it until it finds an entry which is neither
    "." nor "..". I suspect that is the only way which approaches 100% >portability across filesystems.

    Using a "find" utility that is compliant with the POSIX standard,
    the shell function – I think –

    is_non-empty_dir()
    (
    ${1:+:} false &&
    ! test -L "$1" &&
    test -d "$1" &&
    test -r "$1" &&
    unset -v -- findsafe &&
    case "$1" in
    (/*) findsafe="$1" ;;
    (*) findsafe=./"$1" ;;
    esac &&
    {
    printf '%s\n' false &&
    find "${findsafe%/}"/ \
    ! -path '*/' \( -prune -o ! -prune \) \
    -exec printf '%s\n' 'exit 0' \; 2> /dev/null
    } | sh
    )

    should test for a readable non‐empty directory.  That can be used to protect "rmdir" from being invoked with a readable non‐empty
    directory:

    if ! is_non-empty_dir "$dir"
    then
    rmdir -- "$dir"
    fi

    Remark: The directory to be removed by the "rmdir" command i. e. by
    the "rmdir()" system call doesn't need to be readable. 
    Unfortunately, the invocation of the find utility in the shell
    function "is_non-empty_dir" above needs the directory to be readable
    else it cannot tell whether the directory is empty or non‐empty.  To
    be safe it regards any unreadable directory as being empty (thus let
    "rmdir" check by itself).

    There is a race condition, of course.  Therefore there really is no
    safe alternative to the "--ignore-fail-on-non-empty" option of the
    GNU "rmdir" command.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Wed Jun 15 00:34:34 2022
    Kaz Kylheku <480-992-1380@kylheku.com>:
    On 2022-06-13, Helmut Waitzmann <nn.throttle@xoxy.net> wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com>:
    Is there some elegant way to test/remove an empty directory?


    I'm not sure:  Does


    { test -d "$dir" && test -s "$dir" ; }

    test for an empty directory? 

    I'm sorry:  I meant to test for an non‐empty directory.

    Then

    The -s test is documented for files. It probably checks the inode
    st_size for zero. If it happens to work for a directory also, by
    doing the same test, then that won't work because a directory is
    never literally empty.do that for directories also, it won't work
    because a directory is never literally empty.

    I tried it on some emtpy and nonempty directories; it's always
    succeeding (indicating non-empty).

    That's too bad!


    By the way, it's inverted: a "test -s f" success means
    that f is *not* empty.

    Yes, that was my intention – the question above was the wrong one: 
    Under the (wrong) assumption that

    test -d "$dir" && test -s "$dir"

    succeeded if and only if "$dir" were a non‐empty directory,


    { test -d "$dir" && test -s "$dir" ; } ||
    rmdir -- "$dir"

    would protect "rmdir" from beeing called on a non‐empty directory. 
    That would have implemented the "--ignore-fail-on-non-empty" option
    of the GNU "rmdir" command.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lew Pitcher@21:1/5 to Janis Papanagnou on Tue Jun 14 22:29:51 2022
    On Mon, 13 Jun 2022 11:43:31 +0200, Janis Papanagnou wrote:

    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null where an
    empty directory will be removed, and the error message in case of
    non-empty directories suppressed. It works, but that way I suppress all
    error information which might have undesired or undetected bad effects.
    So I was looking for some test based approach like [[...]] && rmdir
    "$dir" but couldn't find simple tests for that (e.g. -d and link count comparison isn't really elegant either, the same with something like ls
    .* * 2>/dev/null and string comparisons, or similar).

    The rmdir(1) command is delegated to the rmdir(2) system call. What
    would rmdir(2) do to determine the emptiness? Would we have to do
    something similar/complex or am I missing something obvious?

    Janis

    With a two-stage delete, you have to be aware of the possible race
    conditions (what is now, colloqually, known as "toctoa" or "time of
    check to time of use"). A external file create may occur in the interval between the time that the check pronounces the directory "empty" and the
    delete attempts to delete it. Similarly, an external file delete that
    empties the directory may occur immediately after the check pronounces
    the directory "not empty". None of the two-stage delete processes, either
    by script, or by utility (like find(1)) accommodate this situation.

    However, even though it is not "pretty", the rmdir(2) call (and the
    rmdir(1) utility) perform an atomic test-and-delete. Your best bet, IMHO,
    is to suppress the rmdir(1) error reporting (such as has been suggested
    with the GNU rmdir(1) --ignore-fail-on-non-empty option) and cope with
    the inelegance of the solution. The alternatives are worse.

    --
    Lew Pitcher
    "In Skills, We Trust"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Lew Pitcher on Tue Jun 14 23:12:42 2022
    On 2022-06-14, Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
    On Mon, 13 Jun 2022 11:43:31 +0200, Janis Papanagnou wrote:

    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null where an
    empty directory will be removed, and the error message in case of
    non-empty directories suppressed. It works, but that way I suppress all
    error information which might have undesired or undetected bad effects.
    So I was looking for some test based approach like [[...]] && rmdir
    "$dir" but couldn't find simple tests for that (e.g. -d and link count
    comparison isn't really elegant either, the same with something like ls
    .* * 2>/dev/null and string comparisons, or similar).

    The rmdir(1) command is delegated to the rmdir(2) system call. What
    would rmdir(2) do to determine the emptiness? Would we have to do
    something similar/complex or am I missing something obvious?

    Janis

    With a two-stage delete, you have to be aware of the possible race
    conditions (what is now, colloqually, known as "toctoa" or "time of
    check to time of use"). A external file create may occur in the interval between the time that the check pronounces the directory "empty" and the delete attempts to delete it.

    In scripting anything involving a subtree with multiple files, you
    almost always assume that there is no interference.

    If you allow concurrency, it will be specific concurrency according
    to your rules: e.g. other instances of your program(s) that observe
    your locking protocol. (Think of, say, how CVS was based on RCS
    commands.)

    Similarly, an external file delete that
    empties the directory may occur immediately after the check pronounces
    the directory "not empty". None of the two-stage delete processes, either
    by script, or by utility (like find(1)) accommodate this situation.

    The one-stage doesn't either.

    Suppose we do

    rmdir nonempty

    Just as that is happening, the nonempty directory is emptied. The rmdir
    syscall is still executing, and returns ENOTEMPTY to user space,
    which is no longer factual.

    However, even though it is not "pretty", the rmdir(2) call (and the
    rmdir(1) utility) perform an atomic test-and-delete.

    It's not atomic right through through to rmdir reporting its error
    message and failed termination status: and who cares.

    Your best bet, IMHO,

    Your best bet is to assume that your script is the only thing acting
    on the given locus of the filesystem, and treat everything else
    as a fork being stuck into a toaster.

    Then trust the modern toaster to ahve a GFCI and fuse, so as not to burn
    down the house.

    is to suppress the rmdir(1) error reporting (such as has been suggested
    with the GNU rmdir(1) --ignore-fail-on-non-empty option) and cope with
    the inelegance of the solution. The alternatives are worse.

    rmdir was entirely in user space once: right thorugh Version 8 Unix.

    It had gaping race conditions in it. It checked the directory for being
    empty other than for the "." nand ".." entries. Then it proceeded to
    remove them, and the directory itself from the parent using unlink
    operations.

    If anything created an object inside that directory in the meanwhile,
    that object would just become garbage, needing to be collected by fsck.

    That's what has to be atomic, for the sake of not leaking disk space
    or corrupting the filesystem.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Janis Papanagnou on Wed Jun 15 01:01:33 2022
    Janis Papanagnou <janis_papanagnou@hotmail.com> writes:

    On 13.06.22 14:58, Ben Bacarisse wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com> writes:

    Is there some elegant way to test/remove an empty directory?

    First, thanks to all for the suggestions and thoughts posted!


    Currently I am unconditionally doing rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects.

    Depending on what rmdir you have, and what your portability requirements
    are, you might find that

    rmdir --ignore-fail-on-non-empty "$dir"

    does what you want.

    This is indeed where I'd consider it best placed, as part of the
    rmdir command - similar to the mkdir command with mkdir -p option.
    (Would be nice if such an option gets standardized.) - Rethinking
    about a separate test; this is probably not that good an idea for
    my case, since I want to remove multiple directories and would want
    to use shell patterns for that, like rmdir -option <date_pattern>
    and individual tests would make a loop over the directory-list
    necessary (which is also not an issue with a 'find'-based approach). Currently I am using that code in a GNU context only, so I can use
    the suggested rmdir option.

    One thing I am wondering, though, is; why isn't there a short form
    of that option available?

    Long options can be abbreviated; in this case all the way down to --i.
    But in a script I'd use the full options since it's typed once.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Helmut Waitzmann on Tue Jun 14 23:43:01 2022
    On 2022-06-14, Helmut Waitzmann <nn.throttle@xoxy.net> wrote:
    Kaz Kylheku <480-992-1380@kylheku.com>:
    On 2022-06-13, Helmut Waitzmann <nn.throttle@xoxy.net> wrote:
    Janis Papanagnou <janis_papanagnou@hotmail.com>:
    Is there some elegant way to test/remove an empty directory?


    I'm not sure:  Does


    { test -d "$dir" && test -s "$dir" ; }

    test for an empty directory? 

    I'm sorry:  I meant to test for an non‐empty directory.

    Then

    The -s test is documented for files. It probably checks the inode
    st_size for zero. If it happens to work for a directory also, by
    doing the same test, then that won't work because a directory is
    never literally empty.do that for directories also, it won't work
    because a directory is never literally empty.

    I tried it on some emtpy and nonempty directories; it's always
    succeeding (indicating non-empty).

    That's too bad!

    BTW, here is how the user space implementation of the rmdir function,
    Version 8 Unix, tested for a non-empty directory:

    while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) {
    if(dir.d_ino == 0) continue;
    if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."))
    continue;
    fprintf(stderr, "%s: %s not empty\n", cmdname, name);
    ++Errors;
    close(fd);
    return;
    }

    Just scanning like this is baked into the Unix DNA.

    https://www.tuhs.org/cgi-bin/utree.pl?file=V8/usr/src/cmd/rmdir/rmdir.c

    The rmdir system call in V9 did something really gross for this.
    It calls a function called dsearch() three times!

    First the directory is searched for the name "/" (guaranteed not to be
    found, for obvious reasons). This has the effect of counting all
    the directory entries.

    Then dsearch() is called two more times, to search for "." and "..".
    For each one that is successful, the previously returned count is
    decremetned.

    Then if the result is positive, the directory is not empty and
    ENOTEMPTY's predecessor is returned: EHASF.

    https://www.tuhs.org/cgi-bin/utree.pl?file=V9/sys/sys/fs.c

    If this syscall version were invoked on a large directory, it would be
    be slower than the original user space implementation in detecting the
    "not empty" condition and bailing.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Patrie@21:1/5 to Janis Papanagnou on Wed Jun 15 05:03:39 2022
    Janis Papanagnou wrote:
    Is there some elegant way to test/remove an empty directory?

    Currently I am unconditionally doing  rmdir "$dir" 2>/dev/null
    where an empty directory will be removed, and the error message
    in case of non-empty directories suppressed. It works, but that
    way I suppress all error information which might have undesired
    or undetected bad effects. So I was looking for some test based
    approach like  [[...]] && rmdir "$dir"  but couldn't find simple
    tests for that (e.g. -d and link count comparison isn't really
    elegant either, the same with something like  ls .* * 2>/dev/null
    and string comparisons, or similar).

    The rmdir(1) command is delegated to the rmdir(2) system call.
    What would rmdir(2) do to determine the emptiness? Would we
    have to do something similar/complex or am I missing something
    obvious?

    Janis

    In zsh:

    rmdir *(D/^F)

    will (attempt to) remove all empty directories in the current directory.

    * = glob (replace with the glob of your choice)

    D = include dotfiles
    / = only directories
    ^ = not
    F = directories with files

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Janis Papanagnou on Wed Jun 15 20:08:19 2022
    On 15.06.22 19:57, Janis Papanagnou wrote:
    On 15.06.22 12:03, Brian Patrie wrote:
    Janis Papanagnou wrote:
    Is there some elegant way to test/remove an empty directory?
    [...]

    In zsh:

       rmdir *(D/^F)

    So assuming that the directories to consider have week numbers as
    names, and if I understand it correctly, that would work fine for
    my case (i.e. also without the 'D') from any shell

      zsh -c 'rmdir W[0-5][0-9](/^F)'

    I spoke too soon. That will produce an error message in case nothing
    matches at the moment.

    How can we control globbing in zsh for non-existing empty directories
    to be not considered an error?

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Brian Patrie on Wed Jun 15 19:57:30 2022
    On 15.06.22 12:03, Brian Patrie wrote:
    Janis Papanagnou wrote:
    Is there some elegant way to test/remove an empty directory?
    [...]

    In zsh:

      rmdir *(D/^F)

    This is interesting and opens a new view for another solution;
    to let the shell globbing determine the directory emptiness.


    will (attempt to) remove all empty directories in the current directory.

      * = glob (replace with the glob of your choice)

      D = include dotfiles
      / = only directories
      ^ = not
      F = directories with files

    First I had to experiment a bit to understand whether the 'D' has
    to be considered to be similar to 'F', i.e. considering dotfiles
    to be or not to be contributing to the directory emptiness, or
    whether it's just affecting the globbing, i.e. considering also
    directories that start with a dot. - The latter is the case.

    So assuming that the directories to consider have week numbers as
    names, and if I understand it correctly, that would work fine for
    my case (i.e. also without the 'D') from any shell

    zsh -c 'rmdir W[0-5][0-9](/^F)'

    WRT race conditions; I'm not asking how zsh is exactly doing that,
    because that topic might not have the relevance it first appeared,
    and less so in my uncritical application case.

    Other [non-testing] (GNU specific) suggestions in this thread have
    been

    rmdir --ignore-fail-on-non-empty W[0-5][0-9]

    find -maxdepth 1 -type d -name "W[0-5][0-9]" -empty -delete

    I think we have a couple options to choose from. - Thanks.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Eric Pozharski@21:1/5 to Janis Papanagnou on Fri Jun 17 08:58:44 2022
    with <t8d76k$1bjp$1@gioia.aioe.org> Janis Papanagnou wrote:
    On 15.06.22 19:57, Janis Papanagnou wrote:
    On 15.06.22 12:03, Brian Patrie wrote:
    Janis Papanagnou wrote:

    *SKIP*
    In zsh: rmdir *(D/^F)
    So assuming that the directories to consider have week numbers as
    names, and if I understand it correctly, that would work fine for my
    case (i.e. also without the 'D') from any shell
    zsh -c 'rmdir W[0-5][0-9](/^F)'
    I spoke too soon. That will produce an error message in case nothing
    matches at the moment.

    This might be A Good Thing(tm). Because you (plural) are doing
    somehting wrong.

    How can we control globbing in zsh for non-existing empty directories
    to be not considered an error?

    zsh -c 'rmdir W[0-5][0-9](N/^F)'

    And see what is about to happen.

    --
    Torvalds' goal for Linux is very simple: World Domination
    Stallman's goal for GNU is even simpler: Freedom

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Patrie@21:1/5 to Eric Pozharski on Fri Jun 17 19:16:14 2022
    Eric Pozharski wrote:
    with <t8d76k$1bjp$1@gioia.aioe.org> Janis Papanagnou wrote:
    On 15.06.22 19:57, Janis Papanagnou wrote:
    On 15.06.22 12:03, Brian Patrie wrote:
    Janis Papanagnou wrote:

    *SKIP*
    In zsh: rmdir *(D/^F)
    So assuming that the directories to consider have week numbers
    as names, and if I understand it correctly, that would work fine
    for my case (i.e. also without the 'D') from any shell
    zsh -c 'rmdir W[0-5][0-9](/^F)'
    I spoke too soon. That will produce an error message in case nothing
    matches at the moment.

    This might be A Good Thing(tm). Because you (plural) are doing
    somehting wrong.

    How can we control globbing in zsh for non-existing empty
    directories to be not considered an error?

    zsh -c 'rmdir W[0-5][0-9](N/^F)'

    And see what is about to happen.

    The "no matches" error is, imho, desirable in an interactive situation.
    But i'm gathering that this is a script situation, and that you don't
    want it returning nonzero if there are no matches.

    N (nullglob) will cause rmdir to get no args if there are no matches,
    which will just yield a different error message. It could be done in a
    for loop:

    zsh -c 'for f in W[0-5][0-9](N/^F) ;do rmdir $f ;done'

    which would also have the benefit of avoiding the dreaded "line too
    long" error (at the expense of forking for each file).

    Meanwhile, if you're going to require zsh, anyway, you might consider
    just doing the whole script in zsh (though i understand if it's complex
    enough that you don't want to go chasing down bashisms or whatnot that
    don't work in zsh).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Brian Patrie on Sat Jun 18 01:20:36 2022
    On 2022-06-18, Brian Patrie <bpatrie@bellsouth.spamisicky.net> wrote:
    N (nullglob) will cause rmdir to get no args if there are no matches,
    which will just yield a different error message. It could be done in a
    for loop:

    zsh -c 'for f in W[0-5][0-9](N/^F) ;do rmdir $f ;done'

    which would also have the benefit of avoiding the dreaded "line too
    long" error (at the expense of forking for each file).

    If you have a way of matching patterns that can come up empty, like the nullglob option in Bash or the above, then a wrapper function like this
    can deal with commands that don't like empty inputs:

    zp() # zero plus
    {
    local command=$1 # Bash-like local var
    shift

    if [ $# -gt 0 ] ; then
    $command "$@"
    else
    true
    fi
    }

    Now just

    zp rmdir <pattern>

    If pattern has an empty expansion (Bash shopt -o nullglob) then zp will
    not run the command.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Brian Patrie on Sat Jun 18 04:42:21 2022
    On 18.06.2022 02:16, Brian Patrie wrote:

    The "no matches" error is, imho, desirable in an interactive situation.
    But i'm gathering that this is a script situation, and that you don't
    want it returning nonzero if there are no matches.

    N (nullglob) will cause rmdir to get no args if there are no matches,
    which will just yield a different error message. It could be done in a
    for loop:

    zsh -c 'for f in W[0-5][0-9](N/^F) ;do rmdir $f ;done'

    which would also have the benefit of avoiding the dreaded "line too
    long" error (at the expense of forking for each file).

    Meanwhile, if you're going to require zsh, anyway, you might consider
    just doing the whole script in zsh (though i understand if it's complex enough that you don't want to go chasing down bashisms or whatnot that
    don't work in zsh).

    Well, ksh'isms in my case. :-) A lot of ksh'isms seem to work in zsh.
    There's some I don't want to transcribe, though.

    So what to do then? - Something like this...?

    zsh -c 'set -o nullglob ; echo W[0-5][0-9](N/^F)' | xargs -r rmdir


    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Eric Pozharski@21:1/5 to Janis Papanagnou on Sat Jun 18 13:10:32 2022
    with <t8je2e$unq$1@dont-email.me> Janis Papanagnou wrote:
    On 18.06.2022 02:16, Brian Patrie wrote:

    *SKIP*
    So what to do then? - Something like this...?
    zsh -c 'set -o nullglob ; echo W[0-5][0-9](N/^F)' | xargs -r rmdir

    You can do better:

    zsh -Gc 'echo W[0-5][0-9](/^F)' | xargs -r rmdir

    --
    Torvalds' goal for Linux is very simple: World Domination
    Stallman's goal for GNU is even simpler: Freedom

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Kaz Kylheku on Sun Jun 19 01:52:39 2022
    On 2022-06-18, Kaz Kylheku <480-992-1380@kylheku.com> wrote:
    if [ $# -gt 0 ] ; then
    $command "$@"

    Better make it $command -- "$@"; if we don't do that, there is no way for
    the caller to work around it because -- will be counted as an argument.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Kaz Kylheku on Sun Jun 19 04:58:03 2022
    On 18.06.2022 03:20, Kaz Kylheku wrote:

    if [ $# -gt 0 ] ; then
    $command "$@"
    else
    true
    fi

    The else-branch is unnecessary; default behavior of 'if' exit status.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Patrie@21:1/5 to Janis Papanagnou on Sun Jun 19 21:51:45 2022
    Janis Papanagnou wrote:
    On 18.06.2022 02:16, Brian Patrie wrote:

    The "no matches" error is, imho, desirable in an interactive
    situation. But i'm gathering that this is a script situation,
    and that you don't want it returning nonzero if there are no
    matches.

    N (nullglob) will cause rmdir to get no args if there are no matches,
    which will just yield a different error message. It could be done
    in a for loop:

    zsh -c 'for f in W[0-5][0-9](N/^F) ;do rmdir $f ;done'

    which would also have the benefit of avoiding the dreaded "line too
    long" error (at the expense of forking for each file).

    Meanwhile, if you're going to require zsh, anyway, you might consider
    just doing the whole script in zsh (though i understand if it's
    complex enough that you don't want to go chasing down bashisms or
    whatnot that don't work in zsh).

    Well, ksh'isms in my case. :-) A lot of ksh'isms seem to work in zsh.

    I gather that many zshisms came from ksh. :)

    There's some I don't want to transcribe, though.

    So what to do then? - Something like this...?

    zsh -c 'set -o nullglob ; echo W[0-5][0-9](N/^F)' | xargs -r rmdir

    (N) should take care of nullglob for you. And, as been pointed out,
    unexpected characters, like newlines, in filenames can byte you in the
    cabouse; so null chars for delimiters, for good measure:

    zsh -c 'printf "%s\0" W[0-5][0-9](N/^F)' | grep -z . | xargs -0r rmdir

    (printf is a builtin in zsh, btw.)

    I had to throw the grep in there to filter out the blank. I don't know
    why the -r didn't take care of it.

    OTOH, i like Kaz's shell function approach, as it avoids the zsh
    dependency; though you're then back to requiring rmdir to support
    the --ignore-fail-on-non-empty option.

    So many options! :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Brian Patrie on Mon Jun 20 16:34:23 2022
    On 2022-06-20, Brian Patrie <bpatrie@bellsouth.spamisicky.net> wrote:
    OTOH, i like Kaz's shell function approach, as it avoids the zsh
    dependency; though you're then back to requiring rmdir to support
    the --ignore-fail-on-non-empty option.

    Right; that trick just solves the problem "I'd like to call a command
    that works with one or more arguments, but what I have is zero or more arguments." Nothing with rmdir semantics.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)