[arch-projects] Fwd: [initscripts] [PATCH] Setting Locale: fix status reporting FAIL erroneously

Kurt J. Bosch kjb-temp-2009 at alpenjodel.de
Sun Jun 26 12:59:09 EDT 2011


Tom Gundersen, 2011-06-26 17:00:
> On Sun, Jun 26, 2011 at 4:06 PM, Dave Reisner<d at falconindy.com>  wrote:
>> On Sun, Jun 26, 2011 at 03:12:24PM +0200, Kurt J. Bosch wrote:
>>> Tom Gundersen, 2011-06-26 13:51:
>>>> On Sun, Jun 26, 2011 at 1:03 PM, Kurt J. Bosch
>>>> <kjb-temp-2009 at alpenjodel.de>    wrote:
>>>>> The following test case (run in a terminal)
>>>>>
>>>>> #!/bin/bash
>>>>>
>>>>> # custom override example
>>>>> stat_busy() {
>>>>>         if (( PUSH_MSG )); then
>>>>>                 # This triggers the error in "$@" below
>>>>>                 # actual code was:
>>>>>                 # echo set message "$1">    "$spl_fifo"&
>>>>>                 :&
>>>>>         fi
>>>>>         echo "$1" BUSY
>>>>> }
>>>>>
>>>>> status() {
>>>>>         stat_busy "$1"
>>>>>         shift
>>>>>         "$@"
>>>>>         local retval=$?
>>>>>         (( retval == 0 ))&&    echo DONE || echo FAIL "($retval)"
>>>>> }
>>>>>
>>>>> PUSH_MSG=0 status "test #0" cat<(echo foo)
>>>>> PUSH_MSG=1 status "test #1" cat<(echo foo)
>>>>
>>>> [...]
>>>>
>>>>> CCing Tom Gundersen.
>>>>
>>>> Thanks.
>>>>
>>>> I have not figured it out, but here is a more minimal test:
>>>>
>>>>
>>>> #!/bin/bash
>>>>
>>>>
>>>> test_one() {
>>>>         :&
>>>>         "$@"
>>>> }
>>>>
>>>> test_two() {
>>>>         :
>>>>         "$@"
>>>> }
>>>>
>>>> # working
>>>> test_one eval 'cat<(echo foo)'
>>>> test_two cat<(echo foo)
>>>>
>>>> #not working
>>>> test_one cat<(echo foo)
>>>
>>> Confirmed.
>>>
>>> --
>>> Kurt
>>
>> Now I see it (at least in Tom's example). It's expected behavior. You're
>> only allowed to read the file descriptor created by a PE once. However,
>> because file descriptors are inherited by subshells, when the subshell
>> ends, the file descriptor is closed and it goes away. Look at what
>> happens when you modify the script slightly:
>>
>> -------------------
>>
>> #!/bin/bash
>>
>> test_one() {
>>   ls /dev/fd/
>>   :&
>>   ls /dev/fd/
>>   "$@"
>> }
>>
>> test_one cat<(echo foo)
>>
>> -------------------
>>
>> And then run it with debug output....
>>
>> +foo[11]: test_one cat /dev/fd/63
>> +foo[4]: ls /dev/fd/
>> ++foo[11]: echo foo
>> 0  1  2  3  63
>> +foo[6]: ls /dev/fd/
>> +foo[5]: :
>> 0  1  2  3
>> +foo[7]: cat /dev/fd/63
>> cat: /dev/fd/63: No such file or directory
>>
>> The subshell inherits the descriptor and closes it on exit, destroying
>> it for the parent. The eval "works" because the FD for the process
>> substitution isn't created until _after_ the subshell.
>>
>> Can we _not_ do this? Our old solution didn't require voodoo like this,
>> and it worked just fine (albeit a few more SLOC). Not everything needs
>> to be a one line operation. Perhaps we could just write a simple
>> function to take care of all these 1 line files that we write to:
>>
>> write_oneline_file() {
>>   local file=$1 line=$2 mode=$3
>>
>>   printf '%s\n' "$line" >"$file"
>>   [[ $mode ]] &&  chmod "$mode" "$file"
>> }
>>
>> Which satisfies both parties, as it appears to be a one liner in
>> execution, but it's actually sane on the back end.
>
> Thanks for your explanation Dave. I like your solution, should make
> things more readable.
>
> -t
>
> [sorry for duplicate, forgot CC]

I would like to go a bit further with this:
a) Drop the 'oneline' and the '\n' to be able to use it for any number 
of lines including zero.
b) Allow more options like owner, group, create parent directory.

Maybe like so:

install_file() {
   local file=$1 content=$2 # remaining args go to install directly
   shift 2
   install -T "$@" <(printf '%s' "$content") "$file"
}

Then these candidates:

  --- rc.sysinit ---
221: install -Tm 0664 -o root -g utmp <(:) /var/run/utmp
264: install -Tm 0600 <( dmesg ) /var/log/dmesg.log
266: install -Tm 0644 <( dmesg ) /var/log/dmesg.log
  --- rc.shutdown ---
24:  install -TDm 0600 <(:) $RANDOM_SEED

could be turned into:

  --- rc.sysinit ---
221: install_file /var/run/utmp "" -m 0664 -o root -g utmp
264: install_file /var/log/dmesg.log "$( dmesg )" -m 0600
266: install_file /var/log/dmesg.log "$( dmesg )" -m 0644
  --- rc.shutdown ---
24:  install_file $RANDOM_SEED "" -m 0600 -D

There is only one small drawback - we would need to add the trailing 
newline explicitly if wanted:

  --- rc.sysinit ---
232: install_file /etc/profile.d/locale.sh "export LANG=$LOCALE"$'\n' -m 
0755

-- 
Kurt


More information about the arch-projects mailing list