bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bash uses tmp files for inter-process communication instead of pipes


From: Pierre Gaston
Subject: Re: bash uses tmp files for inter-process communication instead of pipes?
Date: Tue, 7 Oct 2014 08:09:39 +0300

On Tue, Oct 7, 2014 at 12:00 AM, Linda Walsh <bash@tlinx.org> wrote:

According to Chet , only way to do a multi-var assignment in bash is
>
>
>>> read a b c d  <<<$(echo ${array[@]})
>>>
>>
>> The redundant $(echo...) there is pretty bizarre.  Then again, that
>> whole command is strange.  You have a nice friendly array and you are
>> assigning the first 3 elements to 3 different scalar variables.  Why?
>> (The fourth scalar is picking up the remainder, so I assume it's the
>> rubbish bin.)
>>
>> Why not simply use the array elements?
>>
>>  Forcing a simple assignment into using a tmp file seems Machiavellian --
>>> as it does exactly the thing the user is trying to avoid through
>>> unexpected means.
>>>
>>
>> You are working in a severely constrained environment.
>>
> That isn't the problem:  the assignment using a tmp file is:
>
>> strace -p 48785 -ff
>>
> Process 48785 attached
> read(0, "\r", 1)                        = 1
> write(2, "\n", 1)                       = 1
> socket(PF_NETLINK, SOCK_RAW, 9)         = 3
> sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
> msg_iov(2)=[{"*\0\0\0d\4\1\0\0\0\0\0\0\0\0\0", 16}, {"read a b c d
> <<<${arr[@]}\0", 26}], msg_controllen=0, msg_flags=0}, 0) = 42
> close(3)                                = 0
> -----
> Um... it used a socket.. to transfer it, then it uses a tmp file on top
> of that?!  :
>
> rt_sigaction(SIGINT, {0x4320b1, [], SA_RESTORER|SA_RESTART, 0x30020358d0},
> {0x4320b1, [], SA_RESTORER|SA_RESTART, 0x30020358d0}, 8) = 0
> open("/tmp/sh-thd-110678907923", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3
> write(3, "one two three four", 18)      = 18
> write(3, "\n", 1)                       = 1
> open("/tmp/sh-thd-110678907923", O_RDONLY) = 4
> close(3)                                = 0
> unlink("/tmp/sh-thd-110678907923")      = 0
> fcntl(0, F_GETFD)                       = 0
> fcntl(0, F_DUPFD, 10)                   = 10
> fcntl(0, F_GETFD)                       = 0
> fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
> dup2(4, 0)                              = 0
> close(4)                                = 0
> ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS,
> 0x7fff85627820) = -1 ENOTTY (Inappropriate ioctl for device)
> lseek(0, 0, SEEK_CUR)                   = 0
> read(0, "one two three four\n", 128)    = 19
> dup2(10, 0)                             = 0
> fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
> close(10)                               = 0
> -----
>
> Why in gods name would it use a socket (still of arguable overhead, when
> it could be done in a local lib), but THEN it duplicates the i/o in a file?
>
>  Thus, you need
>> to adapt your code to that environment.  This may (often will) mean
>> you must forsake your usual practices, and fall back to simpler
>> techniques.
>>
> ----
>         The above is under a normal environment.  It's still broken.
>
>
>
>
>
>> Maybe the best solution here is to move your script to a different part
>> of the boot sequence.  If you run it after all the local file systems
>> have been mounted, then you should be able to create temporary files,
>> which in turns means << and <<< become available, should you need them.
>>
> ----
>         Theoretically, they ARE mounted.... What I think may be happening
> is that $TMP is not set so it is trying to open the tmp dir in:
>
> "//sh-thd-183928392381" -- a network address.
>
>
>  Elegance must be the first sacrifice upon the altar, here.
>>
> ---
>         Correctness before elegance.  1), use memory before OS services.
> 2) use in-memory services before file services, 3) Don't use uninitialized
> variables (TMP) -- verify that they are sane values before usage.
> 4) don't use network for tmp when /tmp or /var/tmp would have worked just
> fine.
>
>
>
>
>>  So why would someone use a tmp file to do an assignment.
>>>
>>
>> It has nothing to do with assignments.  Temp files are how here documents
>> (and their cousin here strings) are implemented.  A here document is a
>> redirection of standard input.  A redirection *from a file*
>>
> ----
>         Nope:
>  This type of redirection instructs the shell to  read  input  from  the
>        current source until a line containing only delimiter (with no
> trailing
>        blanks) is seen.  All of the lines read up to that point are then
> used
>        as the standard input for a command.
>
> "The current source" -- can be anything that input can be
> redirected from -- including memory.
>
>
>  in fact,
>> albeit a file that is created on the fly for you by the shell.
>>
> ----
> Gratuitous expectation of slow resources...  Non-conservation
> of resources, not for the user, but for itself.
>
> Note:
>
>> a=$(<foo)
>> echo "$a"
>>
> one
> two
> three
> ---
> no tmp files used, but it does a file read on foo.
>
> b=$a
> -- the above uses no tmp files.
>
> b=$(echo "$a")
> ---
> THAT uses no tmp files.
>
> But
> b=<<<$a
>
> uses a tmp file.
>
> That's ridiculously lame.
>

b=<<<$a is not doing anything so I wonder how much value this example has.

A pipe means 2 different processes, a tempfile for a heredoc does not.
Why force people to use a fork when it's not necessary?
I don't even mean that as an argument, just as an example that "a pipe" is
not just a simple drop in replacement with no consequences.

Besides your comparison is simply ludicrous, bash provides several
mechanisms do to several very different things. That you use them in clever
ways to achieve something that very superficially looks the same doesn't
mean they have no other use for which "using the memory" is just not
possible.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]