• Re: Long filenames in DOS/Windows and Unix/Linux

    From Lawrence D'Oliveiro@21:1/5 to Richard Kettlewell on Sat Aug 31 23:34:22 2024
    XPost: comp.unix.shell

    On Sat, 31 Aug 2024 09:27:44 +0100, Richard Kettlewell wrote:

    (I’ll be disappointed in extreme cases of course, e.g. filesystems that permit ‘/’ in filenames, but the scale of the problem can be minimized.)

    The nice thing about Unicode is the alternatives it offers: so you can’t
    use “/” in a filename, but you can use “∕” instead.

    I think the thing that makes it hard is not the spaces as such, but the tooling that makes it inconvenient to handle them, which primarily means Bourne shell parsing rules. The problem basically ceases to exist once you’re outside the shell ecosystem.

    The rest of Unix has evolved substantially since the 1970s but shell is
    still stuck in this particular trap. It’s like we’re still making making arrowheads out of flint but everything else from steel.

    If you avoid newlines in filenames, Posix shells can cope with anything
    else if you set “IFS=$'\n'”.

    If you insist on wanting to accept those as well, then I don’t think Posix
    is enough, but Bash does have facilities that help you cope.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sun Sep 1 07:03:31 2024
    XPost: comp.unix.shell

    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with anything
    else if you set “IFS=$'\n'”.

    Sorry, no, it looks like the “$'...'” syntax for string literals is not from Posix, it’s a Bash-ism.

    I think it’s still possible to assign a newline to $IFS, it just takes a
    bit more work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nuno Silva@21:1/5 to Lawrence D'Oliveiro on Sun Sep 1 09:10:00 2024
    XPost: comp.unix.shell

    On 2024-09-01, Lawrence D'Oliveiro wrote:

    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with anything
    else if you set “IFS=$'\n'”.

    Sorry, no, it looks like the “$'...'” syntax for string literals is not from Posix, it’s a Bash-ism.

    I think it’s still possible to assign a newline to $IFS, it just takes a bit more work.

    Perhaps using the printf utility? It is in IEEE 1003.1 (p3049 in -2008).

    --
    Nuno Silva

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From candycanearter07@21:1/5 to Richard Kettlewell on Sat Sep 7 18:20:03 2024
    Richard Kettlewell <invalid@invalid.invalid> wrote at 17:21 this Thursday (GMT):
    Ralf Fassel <ralfixx@gmx.de> writes:
    * Richard Kettlewell <invalid@invalid.invalid>
    | Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    | > [...] For example, I might type something like:
    | >
    | > for file in * ; do cp -p $file $file.bak ; done
    |
    | That’s the heart of the matter. Field splitting happens after
    | parameter expansion.

    Only sometimes it doesn't :-)

    $ foo="foo bar"
    $ bar=$foo

    No problem with the space in the expanded value here!

    $ echo $bar
    foo bar

    but of course:
    ls $bar
    ls: cannot access 'foo': No such file or directory
    ls: cannot access 'bar': No such file or directory

    Fair point. “Field splitting happens after parameter expansion, except
    when it doesn’t”.


    Actually, echo is special since it just prints every argument it's
    given.. both of these commands are working as expected with splitting:

    $ echo some text

    some text

    $ ls some text

    ls: cannot access 'some': No such file or directory
    ls: cannot access 'text': No such file or directory
    --
    user <candycane> is generated from /dev/urandom

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Lawrence D'Oliveiro on Sun Sep 8 07:24:02 2024
    XPost: comp.unix.shell

    On 01.09.2024 09:03, Lawrence D'Oliveiro wrote:
    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with anything
    else if you set “IFS=$'\n'”.

    Sorry, no, it looks like the “$'...'” syntax for string literals is not from Posix, it’s a Bash-ism.

    Note that it's not a "Bash-ism" - Bash was rarely the _inventor_ of
    any shell features, mostly adopted them from other shells, primarily
    from Kornshell (still, by far, not catching up).

    Kornshell documented that specific feature with its 1993 version.

    And we've learned from other replies that it's meanwhile - 30 years
    later - already in POSIX. (Good news!)

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Sun Sep 1 19:51:09 2024
    XPost: comp.unix.shell

    Lawrence D'Oliveiro <ldo@nz.invalid>:
    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with
    anything else if you set “IFS=$'\n'”.


    Sorry, no, it looks like the “$'...'” syntax for string literals
    is not from Posix, it’s a Bash-ism.


    I think it’s still possible to assign a newline to $IFS, it just
    takes a bit more work.


    newline="$( printf '%b.' '\n' )" && newline="${newline%?}"


    As this is a problem with the shell, I suggest Followup-To
    "comp.unix.shell"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Sun Sep 1 20:06:17 2024
    XPost: comp.unix.shell

    Lawrence D'Oliveiro <ldo@nz.invalid>:
    On Sat, 31 Aug 2024 09:27:44 +0100, Richard Kettlewell wrote:

    I think the thing that makes it hard is not the spaces as such,
    but the tooling that makes it inconvenient to handle them,
    which primarily means Bourne shell parsing rules. The problem
    basically ceases to exist once you’re outside the shell
    ecosystem.


    The rest of Unix has evolved substantially since the 1970s but
    shell is still stuck in this particular trap. It’s like we’re
    still making making arrowheads out of flint but everything else
    from steel.


    If you avoid newlines in filenames, Posix shells can cope with
    anything else if you set “IFS=$'\n'”.


    If you insist on wanting to accept those as well, then I don’t
    think Posix is enough, but Bash does have facilities that help
    you cope.


    If one wants to cope with any character (including newline
    characters) in the POSIX shell's command line, one could make use
    of the apostroph quoting mechanism.


    If one wants to process arbitrary (may be generated) lists of
    filenames, one could make use of the "xargs" utility with option
    "-0".


    To generate those lists of filenames, there are

    find ... -print0


    and


    printf '%s\0' ...


    available.

    Followup-To: comp.unix.shell

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Sun Sep 1 21:07:28 2024
    XPost: comp.unix.shell

    Lawrence D'Oliveiro <ldo@nz.invalid>:
    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with
    anything else if you set “IFS=$'\n'”.


    Sorry, no, it looks like the “$'...'” syntax for string literals
    is not from Posix, it’s a Bash-ism.


    Thanks to the newest POSIX standard, this is part of the
    standard:


    <https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_02_04>


    Followup-To: comp.unix.shell

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Ralf Fassel on Tue Sep 10 07:17:48 2024
    On 05.09.2024 11:29, Ralf Fassel wrote:
    * Richard Kettlewell <invalid@invalid.invalid>
    | Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    | > [...] For example, I might type something like:
    | >
    | > for file in * ; do cp -p $file $file.bak ; done

    Quoting is generally the standard way to be on the safe side...

    for file in * ; do cp -p "$file" "$file.bak" ; done


    | That’s the heart of the matter. Field splitting happens after parameter
    | expansion.

    Only sometimes it doesn't :-)

    $ foo="foo bar"
    $ bar=$foo

    No problem with the space in the expanded value here!

    $ echo $bar
    foo bar

    There is a problem also with 'echo'...!

    space="foo bar"
    two_spaces="two spaces"
    a_tab="a tab"

    # all the IFSs get collapsed in:
    echo $space
    echo $two_spaces
    echo $a_tab

    # correct way to handle that:
    echo "$space"
    echo "$two_spaces"
    echo "$a_tab"


    but of course:
    ls $bar
    ls: cannot access 'foo': No such file or directory
    ls: cannot access 'bar': No such file or directory

    It's documented in bash(1):

    PARAMETERS
    [...]
    A variable may be assigned to by a statement of the form

    name=[value]

    [...] Word splitting is not performed, with the exception of
    "$@" as explained below under Special Parameters.

    but I find it confusing nevertheless.

    It's not that confusing if you know the difference between a shell
    construct (that doesn't require quotes) and "the all rest" that
    needs (for the general case) quotes. If in doubt there's the rule
    of thumb to always use quotes.

    Janis


    R'


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Wayne@21:1/5 to Lawrence D'Oliveiro on Tue Sep 3 13:56:08 2024
    XPost: comp.unix.shell

    On 9/1/2024 3:03 AM, Lawrence D'Oliveiro wrote:
    I wrote:

    If you avoid newlines in filenames, Posix shells can cope with anything
    else if you set “IFS=$'\n'”.

    Sorry, no, it looks like the “$'...'” syntax for string literals is not from Posix, it’s a Bash-ism.

    Actually, dollar quotes were added to POSIX as of SUS Issue 8:

    "2.2.4 Dollar-Single-Quotes
    A sequence of characters starting with a <dollar-sign> immediately followed
    by a single-quote ($') shall preserve the literal value of all characters up to an unescaped terminating single-quote ('), with the exception of certain <backslash>-escape sequences, as follows:
    ..."

    <https://pubs.opengroup.org/onlinepubs/9799919799/>

    --
    Wayne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Wayne on Tue Sep 3 21:54:34 2024
    XPost: comp.unix.shell

    On Tue, 3 Sep 2024 13:56:08 -0400, Wayne wrote:

    On 9/1/2024 3:03 AM, Lawrence D'Oliveiro wrote:

    Sorry, no, it looks like the “$'...'” syntax for string literals is not >> from Posix, it’s a Bash-ism.

    Actually, dollar quotes were added to POSIX as of SUS Issue 8:

    Glad to know. I was looking at the man page for dash(1) as my reference
    for a vanilla POSIX shell.

    <https://manpages.debian.org/1/dash.1.en.html>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Tue Sep 3 22:18:32 2024
    On Tue, 03 Sep 2024 15:16:36 -0700, Keith Thompson wrote:

    For example, I might type something like:

    for file in * ; do cp -p $file $file.bak ; done

    It’s quite easy to fix that to work with spaces in file names. How long
    have you been working with *nix shells?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Lawrence D'Oliveiro on Tue Sep 3 22:59:42 2024
    Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    On Tue, 03 Sep 2024 15:16:36 -0700, Keith Thompson wrote:

    For example, I might type something like:

    for file in * ; do cp -p $file $file.bak ; done

    It’s quite easy to fix that to work with spaces in file names. How long >have you been working with *nix shells?

    Longer than you.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Tue Sep 3 23:54:35 2024
    On Tue, 03 Sep 2024 16:10:42 -0700, Keith Thompson wrote:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    On Tue, 03 Sep 2024 15:16:36 -0700, Keith Thompson wrote:

    For example, I might type something like:

    for file in * ; do cp -p $file $file.bak ; done

    It’s quite easy to fix that to work with spaces in file names.

    I wouldn't call it "quite easy".

    As easy as this, in Bash at least:

    IFS=$'\n'

    I’ve been told elsewhere that $'\n' is also valid in the latest Posix
    spec.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Tue Sep 3 23:56:55 2024
    On Tue, 03 Sep 2024 16:38:06 -0700, Keith Thompson wrote:

    The make utility has no support for paths with spaces.

    Looks like you're right.

    I have some Makefiles with spaces in the dependency names, of the form:

    target\ name\ with\ space : source\ name\ with\ space

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Keith Thompson on Tue Sep 3 23:15:46 2024
    On 2024-09-03, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    John Ames <commodorejohn@gmail.com> writes:
    On Tue, 3 Sep 2024 20:11:28 -0000 (UTC)
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:

    Because it is based on a strawman interpretation of the "no spaces"
    rule. That strawman interpretation is that there are no other rules
    used in combination with the "no spaces" rule, and thus that any
    ridiculous name is fine, just as long as it doesn't contain spaces.

    And so, look how unreadable is this 100 character name in CamelCase!
    Q.E.D. no spaces is a bad recommendation!

    Well, there were no other factors *presented* alongside the blanket
    statement that spaces in filenames are unnecessary, so it would appear
    on the face of it to be an accurate assessment of the claim being made,
    which wasn't in a post of yours to begin with.

    And I'd still like to know who died and made whom king where filenames
    and spaces therein are concrned.

    There is no official "rule" about spaces in filenames, though I can
    imagine easily imagine that some organizations and projects have
    rules forbidding them. A couple of data points: The gcc git repo
    contains 137394 files and none of them have spaces in their names.

    The GCC project is Makefile-based.

    The make utility has no support for paths with spaces.

    Use of make is a great repellant against spaces in names.

    If a make variable contains spaces, there is no way to quote it within
    make. There is no way to express a prerequisite or target name with
    spaces. GNU Make text processing constructs like $(foreach ...)
    don't deal with spaces; there is no way for them to identify items
    that contain spaces.

    The Linux kernel git repo contains 85803 files, and exactly one has
    spaces in its name.

    You can bet it's one that's not referenced in any Makefile.

    Spaces in file names are likely not to be an issue if you interact
    with the filesystem via a GUI like Windows Explorer *or* if you use
    a scripting language like Perl or Python that requires strings used
    as filenames to be enclosed in quotation marks. In those contexts,
    space is just another character.

    The buffoons that use spaces in document names in GUIs will find some
    way to confuse themselves, like typing two spaces instead of one, or
    quoting names to each other in e-mails without enough delimitation or
    use of typeface to know which words are part of the name and which are surrounding text.

    E.g.

    A: "Can you send the file analysis and report to me?"
    B: "I will report to you, but I can't find the file analysis."
    A: "No, the file is called analysis and report. :) Send that to me."

    If you follow the convention that name of a file is one word that
    contains no leading or trailing punctuation, then you can use it in
    written sentences without ambiguity or quotes around it.
    You can put a period or comma after it, and know that it can't
    be part of the name since it would constitute trailing punctuation.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Tue Sep 3 17:35:35 2024
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    How long have you been working with *nix shells?

    A long time. [...]

    My answer is not very long; less than 50 years.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Wed Sep 4 00:41:55 2024
    On Tue, 03 Sep 2024 17:19:17 -0700, Keith Thompson wrote:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    I have some Makefiles with spaces in the dependency names, of the form:

    target\ name\ with\ space : source\ name\ with\ space

    I'd be interested in knowing how you do that.

    $ cat Makefile foo\ bar: foo\ bar.c
    $ make cc foo bar.c -o foo bar
    cc: fatal error: input file ‘foo’ is the same as output file
    compilation terminated.

    The Makefiles in question are not using the default build rules for C
    code: they are building other things, with explicit use of the "$<" and
    "$@" variable substitutions.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Wed Sep 4 00:44:39 2024
    On Tue, 03 Sep 2024 17:27:34 -0700, Keith Thompson wrote:

    Second attempt:

    IFS='\n' ; for file in * ; do cp -p $file $file.bak ; done

    but that leaves IFS set to its new value in my interactive shell.

    Which in my experience is no biggie.

    Next step: what if you wanted to handle newlines in file names as well?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Wed Sep 4 07:05:38 2024
    On Tue, 03 Sep 2024 21:36:48 -0700, Keith Thompson wrote:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    Next step: what if you wanted to handle newlines in file names as well?

    Either `find ... -print0 | xargs -0 ...` or a quick Perl script.

    Sure, it’s much easier in Perl or Python or some other such programming- oriented (as opposed to command-oriented) language. But it can be done in
    Bash.

    The thing is, while find is handy for getting the matching file names,
    xargs is not always the most convenient way of processing them. You often
    just want to be able to do “for f in «filenames»; do «whatever» done”, e.g.:

    collect_expand «wildcard» found_filenames
    for f in "${found_filenames[@]}"; do
    echo "found" $(printf %q "$f")
    done

    That “collect_expand” is a Bash function. Do you want to figure out how to write it, before I post my solution? ;)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Keith Thompson on Wed Sep 4 06:49:16 2024
    On Tue, 03 Sep 2024 21:29:24 -0700, Keith Thompson wrote:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    The Makefiles in question are not using the default build rules for C
    code: they are building other things, with explicit use of the "$<" and
    "$@" variable substitutions.

    I'd still be interested in seeing an example.

    Here’s one I whipped up:

    --
    output\ file : input\ file
    cp "$<" "$@"

    input\ file : /dev/null
    cp "$<" "$@"
    --

    If the tabs don’t make it across, you know where they should go. ;)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Wed Sep 4 11:47:53 2024
    * Lawrence D'Oliveiro <ldo@nz.invalid>
    | On Tue, 03 Sep 2024 16:10:42 -0700, Keith Thompson wrote:

    | > Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    | >>
    | >> On Tue, 03 Sep 2024 15:16:36 -0700, Keith Thompson wrote:
    | >>>
    | >>> For example, I might type something like:
    | >>>
    | >>> for file in * ; do cp -p $file $file.bak ; done
    | >>
    | >> It’s quite easy to fix that to work with spaces in file names.
    | >
    | > I wouldn't call it "quite easy".

    | As easy as this, in Bash at least:

    | IFS=$'\n'

    Forgive my ignorance, but what is wrong with

    for file in * ; do cp -p "$file" "$file.bak" ; done

    ? Works for both spaces and newlines in file names... (at least with
    bash and ksh).

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nuno Silva@21:1/5 to Keith Thompson on Wed Sep 4 10:16:54 2024
    On 2024-09-04, Keith Thompson wrote:

    Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    On Tue, 03 Sep 2024 17:19:17 -0700, Keith Thompson wrote:
    Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    I have some Makefiles with spaces in the dependency names, of the form: >>>>
    target\ name\ with\ space : source\ name\ with\ space

    I'd be interested in knowing how you do that.

    [I tried to restore the newlines at the appropriate places here, I hope
    I got these right:]
    $ cat Makefile
    foo\ bar: foo\ bar.c
    $ make
    cc foo bar.c -o foo bar
    cc: fatal error: input file ‘foo’ is the same as output file
    compilation terminated.

    The Makefiles in question are not using the default build rules for C
    code: they are building other things, with explicit use of the "$<" and
    "$@" variable substitutions.

    I'd still be interested in seeing an example. In a quick experiment,
    I wasn't able to get GNU Make to recognize the existence of a file named
    "foo bar".

    But, in your output, what is having trouble is the compiler invocation,
    not make itself processing the files (although that then *is* a problem
    with make's implicit rules and their ability to handle spaces).

    Or do you mean there is also a problem with detecting the presence or
    absence of files with spaces in their names?

    --
    Nuno Silva

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nuno Silva@21:1/5 to Keith Thompson on Wed Sep 4 13:33:25 2024
    On 2024-09-04, Keith Thompson wrote:

    Ralf Fassel <ralfixx@gmx.de> writes:
    * Lawrence D'Oliveiro <ldo@nz.invalid>
    | On Tue, 03 Sep 2024 16:10:42 -0700, Keith Thompson wrote:

    | > Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    | >>
    | >> On Tue, 03 Sep 2024 15:16:36 -0700, Keith Thompson wrote:
    | >>>
    | >>> For example, I might type something like:
    | >>>
    | >>> for file in * ; do cp -p $file $file.bak ; done
    | >>
    | >> It’s quite easy to fix that to work with spaces in file names.
    | >
    | > I wouldn't call it "quite easy".

    | As easy as this, in Bash at least:

    | IFS=$'\n'

    Forgive my ignorance, but what is wrong with

    for file in * ; do cp -p "$file" "$file.bak" ; done

    ? Works for both spaces and newlines in file names... (at least with
    bash and ksh).

    You're absolutely right. I'm not sure how I missed that. (I was
    thinking that * just expands to a string, but that's obviously not the
    case.)

    D'oh!

    (Along with these quotes, I'd add ./ before $file.)

    --
    Nuno Silva

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Keith Thompson on Wed Sep 4 14:30:06 2024
    On 2024-09-04, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    On Tue, 03 Sep 2024 16:38:06 -0700, Keith Thompson wrote:
    The make utility has no support for paths with spaces.

    Looks like you're right.

    I have some Makefiles with spaces in the dependency names, of the form:

    target\ name\ with\ space : source\ name\ with\ space

    I'd be interested in knowing how you do that.

    $ cat Makefile
    foo\ bar: foo\ bar.c
    $ make
    cc foo bar.c -o foo bar
    cc: fatal error: input file ‘foo’ is the same as output file
    compilation terminated.
    make: *** [<builtin>: foo bar] Error 1

    If you write your own rule in which $@ is quoted as '$@', it will
    work, provided it doesn't contain ' characters.

    It looks like there is limited support in GNU Make for backslash
    escapes: they can be used on the prerequisite and target names
    in a rule.

    Elsewhere, other than backslash-newline continuations, backslashes
    are literal.

    So we can do:

    FOOBAR := foo\ bar # literal backslash here

    $(FOOBAR) : ... # backslash from variable interpolates here

    Once the backslash is interpolated into the rule head, it becomes
    active, so a single target "foo bar" is specified.

    (Unfortunately, what GNU Make should be arguably be doing here is not
    just treating foo\ bar as the single target foo bar but also
    preserving the backslash so that the item is foo\ bar. Then it would
    be possible for the implicit rule to work, because $@ would produce
    foo\ bar which would be passed on to the shell, where the backslash
    would do its job. One slight problem with that, though, is that the
    interpreter for processing recipes is configurable; it doesn't have
    to be a POSIX-like shell.)

    Anyway, the FOOBAR variable is understood to contain two words, {foo\}
    and {bar}. If we do a patsubst on it, it will match separately against
    the two. Or foreach will iterate over two items. None of the text
    processing stuff in GNU Make will recognize the backslash escape
    as preventing word splitting.

    Nontrivial Makefiles almost always work with lists, like at the
    very least OBJS, SRCS and whatnot.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Muttley@dastardlyhq.com@21:1/5 to All on Wed Sep 4 15:57:24 2024
    On Wed, 4 Sep 2024 08:41:03 -0700
    John Ames <commodorejohn@gmail.com> boringly babbled:
    On Tue, 3 Sep 2024 23:15:46 -0000 (UTC)
    Kaz Kylheku <643-408-1753@kylheku.com> wrote:

    The make utility has no support for paths with spaces.

    Use of make is a great repellant against spaces in names.

    If a make variable contains spaces, there is no way to quote it within
    make. There is no way to express a prerequisite or target name with
    spaces. GNU Make text processing constructs like $(foreach ...)
    don't deal with spaces; there is no way for them to identify items
    that contain spaces.

    If the make utility has no provisions for coping with a subset of legal >filenames, that would seem to be a deficiency in make.

    Given 99.99% of make use cases are to build binaries from source code and
    no sane person would put spaces in the filenames of either, I doubt the developers of make or its users could care less.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Kettlewell@21:1/5 to Keith Thompson on Wed Sep 4 18:03:27 2024
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Spaces in file names are likely not to be an issue if you interact
    with the filesystem via a GUI like Windows Explorer *or* if you use
    a scripting language like Perl or Python that requires strings used
    as filenames to be enclosed in quotation marks. In those contexts,
    space is just another character.

    It can be a real issue if you're interacting via shell commands.
    If I happen to know that none of the files I'm working with have
    spaces (or other problematic characters) in their names, a lot of
    things become easier -- but risky if there's a funny character I'm
    not aware of. For example, I might type something like:

    for file in * ; do cp -p $file $file.bak ; done

    That’s the heart of the matter. Field splitting happens after parameter expansion. The languages that don’t have trouble with spaces in
    filenames[1] don’t do it that way. I suspect if some different design decisions had been made long ago, nobody would be inferring from the difficulties shell scripts have handling strings with spaces in that
    they were unnecessary or even forbidden in filenames.

    [1] or any other kind of string. Let’s not get tunnel vision about
    filenames: shell has trouble with spaces in other contexts too.

    Tcl is the most instructive example: it has a similar word-base
    structure to shell, but largely without getting into the same tangles
    over spaces.

    It would be ideal, I suppose, if interactive shells dealt better with
    spaces in file names, but I'm not sure how that could be achieved. In current shells, removing two files named "foo" and "bar" is easy, and removing a single file named "foo bar" requires some extra effort. I
    find that to be a good tradeoff.

    Agreed. I note that tab completion normally adds any quotes needed,
    which deals with most of the issues in interactive mode, for me.

    As well as the above observations about shell syntax we could also
    wonder whether it was ever really necessary to use the same syntax both
    for interactive file management and a programming language.

    --
    https://www.greenend.org.uk/rjk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Sep 5 11:29:14 2024
    * Richard Kettlewell <invalid@invalid.invalid>
    | Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    | > [...] For example, I might type something like:
    | >
    | > for file in * ; do cp -p $file $file.bak ; done

    | That’s the heart of the matter. Field splitting happens after parameter
    | expansion.

    Only sometimes it doesn't :-)

    $ foo="foo bar"
    $ bar=$foo

    No problem with the space in the expanded value here!

    $ echo $bar
    foo bar

    but of course:
    ls $bar
    ls: cannot access 'foo': No such file or directory
    ls: cannot access 'bar': No such file or directory

    It's documented in bash(1):

    PARAMETERS
    [...]
    A variable may be assigned to by a statement of the form

    name=[value]

    [...] Word splitting is not performed, with the exception of
    "$@" as explained below under Special Parameters.

    but I find it confusing nevertheless.

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Kettlewell@21:1/5 to Ralf Fassel on Thu Sep 5 18:21:15 2024
    Ralf Fassel <ralfixx@gmx.de> writes:
    * Richard Kettlewell <invalid@invalid.invalid>
    | Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    | > [...] For example, I might type something like:
    | >
    | > for file in * ; do cp -p $file $file.bak ; done
    |
    | That’s the heart of the matter. Field splitting happens after
    | parameter expansion.

    Only sometimes it doesn't :-)

    $ foo="foo bar"
    $ bar=$foo

    No problem with the space in the expanded value here!

    $ echo $bar
    foo bar

    but of course:
    ls $bar
    ls: cannot access 'foo': No such file or directory
    ls: cannot access 'bar': No such file or directory

    Fair point. “Field splitting happens after parameter expansion, except
    when it doesn’t”.

    --
    https://www.greenend.org.uk/rjk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Kettlewell@21:1/5 to Kenny McCormack on Sat Aug 31 09:27:44 2024
    gazelle@shell.xmission.com (Kenny McCormack) writes:
    Two comments about spaces in filenames (and Windows vs. Unix):

    1) Windows is actually quite a bit more restrictive about characters in
    filenames than Unix. Which is a good thing. I've always thought
    the "anything other than NUL and /" in Unix was a bad thing and
    encouraged all manner of bad/malicious outcomes. Yet, there are
    people (and I use the term loosely) who think otherwise.

    The historical advantage of the free-for-all Unix approach is that
    allowed flexibility in filename encoding. Today it’d work to say “UTF-8 only” (and maybe other restrictions) but that wasn’t always the case.
    The original design has saved us from a bit of path dependency.

    In the application-facing API (open, CreateFile, etc), the rule pretty
    much has to be ‘anything goes’, because you may be dealing with a ‘foreign’ filesystem (e.g. via a network filesystem). I don’t want to be unable to access an existing file just because two computers have
    different sets of restrictions on filenames.

    (I’ll be disappointed in extreme cases of course, e.g. filesystems that permit ‘/’ in filenames, but the scale of the problem can be minimized.)

    2) Spaces in filenames are pretty much a necessity from the end-user
    POV (but see below). Yes, it makes things hard for us on the admin
    side of the game.

    I think the thing that makes it hard is not the spaces as such, but the
    tooling that makes it inconvenient to handle them, which primarily means
    Bourne shell parsing rules. The problem basically ceases to exist once
    you’re outside the shell ecosystem.

    The rest of Unix has evolved substantially since the 1970s but shell is
    still stuck in this particular trap. It’s like we’re still making making arrowheads out of flint but everything else from steel.

    --
    https://www.greenend.org.uk/rjk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Muttley@dastardlyhq.com@21:1/5 to All on Sat Aug 31 08:39:21 2024
    On Sat, 31 Aug 2024 09:27:44 +0100
    Richard Kettlewell <invalid@invalid.invalid> gabbled: >gazelle@shell.xmission.com (Kenny McCormack) writes:
    2) Spaces in filenames are pretty much a necessity from the end-user
    POV (but see below). Yes, it makes things hard for us on the admin
    side of the game.

    I think the thing that makes it hard is not the spaces as such, but the >tooling that makes it inconvenient to handle them, which primarily means >Bourne shell parsing rules. The problem basically ceases to exist once >you’re outside the shell ecosystem.

    The rest of Unix has evolved substantially since the 1970s but shell is
    still stuck in this particular trap. It’s like we’re still making making >arrowheads out of flint but everything else from steel.


    When parsing is based around words on a line how else exactly would you expect it to be done? Every language tokenises based in seperators so unless you expect the shell to automagically figure out when a filename ends and the next part of the command begins then I would suggest using quotes is a solution thats worked for decades and works fine.

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