• Re: Implicit String-Literal Concatenation

    From Janis Papanagnou@21:1/5 to Janis Papanagnou on Wed Feb 28 01:03:52 2024
    On 28.02.2024 00:50, Janis Papanagnou wrote:
    On 28.02.2024 00:10, Lawrence D'Oliveiro wrote:
    On Tue, 27 Feb 2024 13:18:20 +0100, Janis Papanagnou wrote:

    On 26.02.2024 21:31, Lawrence D'Oliveiro wrote:

    Question: How would you do two separate <<-strings in the same shell
    command?

    Can you give an example what you intend here? (With what semantics?)

    Since '<<' is redirecting the here-document text to stdin of the command >>> you can have only one channel.

    Perl lets you do something like

    func(<<EOD1, <<EOD2);
    ... contents of first string ...
    EOD1
    ... contents of second string ...
    EOD2

    But this doesn’t work in Bash. However, in a Posix shell, remember you can >> specify the number of the file descriptor you want to redirect, e.g.

    diff -u /dev/fd/8 /dev/fd/9 8<<'EOD1' 9<<'EOD2'
    ... contents of first string ...
    EOD1
    ... contents of second string ...
    EOD2

    Note I add the single quotes to prevent expansion of “$”-sequences within
    the strings. (I think this might be needed in Perl, too.)

    I see. - Yes, you can do that in POSIX shells as well. [...]

    You found a syntactic solution already, but that requires some
    non-standard /dev/fd OS support. Newer shells allow also process
    substitution diff <(...) <(...) to support pipes where files
    are expected, but that also relies on the existence of /dev/fd,
    AFAICT.

    With standard mechanisms when I want to read from two individual
    stdin sources I do (for example) something like

    exec 3<&0
    while read <&3 ; read <&3 ; read <&3 # every 3rd line data #1
    do echo $REPLY
    read ; read ; echo $REPLY # every 2nd line data #2
    done 3<<EOT1 <<EOT2
    line 1
    line 2
    line 3
    line 4
    line 5
    line 6
    line 7
    EOT1
    line A
    line B
    line C
    line D
    line E
    EOT2

    With actually the same syntax at least for the here documents.

    Otherwise, in your diff sample, use named pipes?

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Janis Papanagnou on Wed Feb 28 15:22:20 2024
    On 2024-02-28, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    You found a syntactic solution already, but that requires some
    non-standard /dev/fd OS support. Newer shells allow also process
    substitution diff <(...) <(...) to support pipes where files
    are expected, but that also relies on the existence of /dev/fd,
    AFAICT.

    Bash, at least, can alternatively use named pipes.
    This is on FreeBSD:

    bash$ cat s
    #!/bin/sh
    echo "$@"
    ls -l "$@"

    bash$ ./s <(echo hello)
    /tmp//sh-np.Uawtgm
    prw------- 1 naddy wheel 0 Feb 28 16:19 /tmp//sh-np.Uawtgm

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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Christian Weisgerber on Wed Feb 28 17:01:58 2024
    On 28.02.2024 16:22, Christian Weisgerber wrote:
    On 2024-02-28, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    You found a syntactic solution already, but that requires some
    non-standard /dev/fd OS support. Newer shells allow also process
    substitution diff <(...) <(...) to support pipes where files
    are expected, but that also relies on the existence of /dev/fd,
    AFAICT.

    Bash, at least, can alternatively use named pipes.

    Yes, below you're using newer shells' process substitution (as I
    also did above). It implicitly requires an OS supporting /dev/fd .

    The original poster (from comp.lang.c) used also a /dev/fd based
    version like this
    diff -u /dev/fd/8 /dev/fd/9 8<<'EOD1' 9<<'EOD2'
    which appears overly complicated and it's explicitly also relying
    on /dev/fd .

    This is on FreeBSD:

    bash$ cat s
    #!/bin/sh
    echo "$@"
    ls -l "$@"

    bash$ ./s <(echo hello)
    /tmp//sh-np.Uawtgm
    prw------- 1 naddy wheel 0 Feb 28 16:19 /tmp//sh-np.Uawtgm


    With the OP's original question:
    Question: How would you do two separate <<-strings in the same
    shell command?
    it would be interesting to see some neat solution that does not
    rely implicitly (by process substitution) or explicitly on /dev/fd .

    The OP gave an example how it can be done in Perl:
    func(<<EOD1, <<EOD2);
    ... contents of first string ...
    EOD1
    ... contents of second string ...
    EOD2
    and is probably seeking a terse alternative in shell.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Janis Papanagnou on Wed Feb 28 18:12:08 2024
    On 2024-02-28, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    Bash, at least, can alternatively use named pipes.

    Yes, below you're using newer shells' process substitution (as I
    also did above). It implicitly requires an OS supporting /dev/fd .

    It does not! That was my point. Bash implements process substitution
    with temporary named pipes on systems where /dev/fd/* may not be
    available:

    bash$ ./s <(echo hello)
    /tmp//sh-np.Uawtgm
    prw------- 1 naddy wheel 0 Feb 28 16:19 /tmp//sh-np.Uawtgm

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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Christian Weisgerber on Thu Feb 29 02:05:10 2024
    On 28.02.2024 19:12, Christian Weisgerber wrote:
    On 2024-02-28, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    Yes, below you're using newer shells' process substitution (as I
    also did above). It implicitly requires an OS supporting /dev/fd .

    It does not! That was my point. Bash implements process substitution
    with temporary named pipes on systems where /dev/fd/* may not be
    available:

    That's interesting! And you are right; the bash man page indeed says:
    "Process substitution is supported on systems that support
    named pipes (FIFOs) or the /dev/fd method of naming open
    files."

    The Bolsky/Korn Kornshell book says that Kornshell supports process substitution on Unix systems that support /dev/fd/ and I'd have
    expected that Bash adopted that from Kornshell (as it did with so
    many Kornshell features). But probably not...

    Or does Kornshell also support it independently of /dev/fd/ also
    with named pipes? (I cannot check that on my system.)

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Janis Papanagnou on Fri Mar 1 20:35:20 2024
    On 2024-02-29, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    The Bolsky/Korn Kornshell book says that Kornshell supports process substitution on Unix systems that support /dev/fd/ and I'd have
    expected that Bash adopted that from Kornshell (as it did with so
    many Kornshell features). But probably not...

    Or does Kornshell also support it independently of /dev/fd/ also
    with named pipes? (I cannot check that on my system.)

    Checking the nearest available ksh93 source, I see:

    #### COMPILE-TIME OPTIONS ####

    ...
    DEVFD Use the more secure /dev/fd mechanism instead of FIFOs for
    process substitutions. On by default on OSs with /dev/fd.
    ...

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

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