Re: [arch-projects] Fwd: [initscripts] [PATCH] Setting Locale: fix status reporting FAIL erroneously
Dave Reisner, 2011-06-26 19:14:
On Sun, Jun 26, 2011 at 06:59:09PM +0200, Kurt J. Bosch wrote:
Tom Gundersen, 2011-06-26 17:00:
On Sun, Jun 26, 2011 at 4:06 PM, Dave Reisner<d@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@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
ACK. I'm good with this. The shell doesn't complain when there's no trailing newline on the locale file. Is it really necessary? Do we have a [CZK]SH user who can weigh in?
d
Don't know, but we add one more line in functions: 504- elif [[ $CONSOLEMAP ]]; then 505: cat <<"EOF" >>/etc/profile.d/locale.sh 506-if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi 507-EOF -- Kurt
participants (1)
-
Kurt J. Bosch