Package: bash
Version: 3.2-4
Severity: normal
The man page for bash states:
for name [ in word ] ; do list ; done
The list of words following in is expanded, generating
a list of
items. The variable name is set to each element of
this list in
turn, and list is executed each time. ...
This has been the expected behavior of for name in word since
the introduction of the Bourne shell, 30 years ago.
In the case of for name in *, bash executes the loop only once
with name set to the entire list of all the files in the current
directory.
This means that a significant number of scripts do not work as
they should.
I have generated the following test cases from a script called
speakupconf that is distributed with the speakup-doc package.
I am sure that I have seen this problem with scripts that I
have written, as well.
The first case is using the script as distributed. I created
the second and third cases by using alternate formats for the
for statement. The forth case uses ls to generate the file
list, and is the only one that works.
Case 1: asterisk adjacent to semicolon
#!/bin/sh
set -x
# script to load/save all the vars in speakup
# speakupconf save or speakupconf load
# if root saves in /etc/speakup/<synth> else in $HOME/.speakup/<synth>
if [ $UID -eq "0" ]; then
SAVEDIR="/etc/speakup"
else
SAVEDIR="$HOME/.speakup"
fi
if [ ! -d /sys/module/speakup/parameters ]; then
echo "no directory /sys/module/speakup/parameters"
exit 0
fi
SYNTH=`cat /sys/module/speakup/parameters/synth`
case "$1" in
*save)
if [ ! -d $SAVEDIR ] ; then
echo creating $SAVEDIR
mkdir $SAVEDIR
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo creating $SAVEDIR/$SYNTH
mkdir $SAVEDIR/$SYNTH
fi
cd /sys/module/speakup/parameters
SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
for f in $SAVELIST; do
cp $f $SAVEDIR/$SYNTH/$f
done
;;
*load)
if [ ! -d $SAVEDIR ] ; then
echo no directory $SAVEDIR
exit 1
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo no directory $SAVEDIR/$SYNTH
exit 1
fi
cd $SAVEDIR/$SYNTH
for f in *; do
if [ -w /sys/module/speakup/parameters/$f ]; then
cat $f >/sys/module/speakup/parameters/$f
fi
done
;;
*)
echo "usage: speakupconf load/save"
exit 1
;;
esac
Results 1:
+ '[' 0 -eq 0 ']'
+ SAVEDIR=/etc/speakup
+ '[' '!' -d /sys/module/speakup/parameters ']'
++ cat /sys/module/speakup/parameters/synth
+ SYNTH=ltlk
+ case "$1" in
+ '[' '!' -d /etc/speakup ']'
+ '[' '!' -d /etc/speakup/ltlk ']'
+ cd /etc/speakup/ltlk
+ for f in '*'
+ '[' -w /sys/module/speakup/parameters/attrib_bleep
/sys/module/speakup/parameters/bell_pos
/sys/module/speakup/parameters/bleeps
/sys/module/speakup/parameters/bleep_time
/sys/module/speakup/parameters/caps_start
/sys/module/speakup/parameters/caps_stop
/sys/module/speakup/parameters/characters
/sys/module/speakup/parameters/chartab
/sys/module/speakup/parameters/cursor_time
/sys/module/speakup/parameters/delay_time
/sys/module/speakup/parameters/delimiters
/sys/module/speakup/parameters/ex_num
/sys/module/speakup/parameters/freq
/sys/module/speakup/parameters/full_time
/sys/module/speakup/parameters/jiffy_delta
/sys/module/speakup/parameters/key_echo
/sys/module/speakup/parameters/keymap
/sys/module/speakup/parameters/lang
/sys/module/speakup/parameters/no_interrupt
/sys/module/speakup/parameters/pitch
/sys/module/speakup/parameters/punc_all
/sys/module/speakup/parameters/punc_level
/sys/module/speakup/parameters/punc_most
/sys/module/speakup/parameters/punc_some
/sys/module/speakup/parameters/punct
/sys/module/speakup/parameters/quiet
/sys/module/speakup/parameters/rate
/sys/module/speakup/parameters/reading_punc
/sys/module/speakup/parameters/repeats
/sys/module/speakup/parameters/say_control
/sys/module/speakup/parameters/say_word_ctl
/sys/module/speakup/parameters/silent
/sys/module/speakup/parameters/spell_delay
/sys/module/speakup/parameters/synth
/sys/module/speakup/parameters/synth_direct
/sys/module/speakup/parameters/tone
/sys/module/speakup/parameters/trigger_time
/sys/module/speakup/parameters/version
/sys/module/speakup/parameters/voice
/sys/module/speakup/parameters/vol ']'
/usr/local/bin/speakupconf: line 43: [: too many arguments
Case 2: space between asterisk and semicolon
#!/bin/sh
set -x
# script to load/save all the vars in speakup
# speakupconf save or speakupconf load
# if root saves in /etc/speakup/<synth> else in $HOME/.speakup/<synth>
if [ $UID -eq "0" ]; then
SAVEDIR="/etc/speakup"
else
SAVEDIR="$HOME/.speakup"
fi
if [ ! -d /sys/module/speakup/parameters ]; then
echo "no directory /sys/module/speakup/parameters"
exit 0
fi
SYNTH=`cat /sys/module/speakup/parameters/synth`
case "$1" in
*save)
if [ ! -d $SAVEDIR ] ; then
echo creating $SAVEDIR
mkdir $SAVEDIR
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo creating $SAVEDIR/$SYNTH
mkdir $SAVEDIR/$SYNTH
fi
cd /sys/module/speakup/parameters
SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
for f in $SAVELIST; do
cp $f $SAVEDIR/$SYNTH/$f
done
;;
*load)
if [ ! -d $SAVEDIR ] ; then
echo no directory $SAVEDIR
exit 1
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo no directory $SAVEDIR/$SYNTH
exit 1
fi
cd $SAVEDIR/$SYNTH
for f in * ; do
if [ -w /sys/module/speakup/parameters/$f ]; then
cat $f >/sys/module/speakup/parameters/$f
fi
done
;;
*)
echo "usage: speakupconf load/save"
exit 1
;;
esac
Results 2:
+ '[' 0 -eq 0 ']'
+ SAVEDIR=/etc/speakup
+ '[' '!' -d /sys/module/speakup/parameters ']'
++ cat /sys/module/speakup/parameters/synth
+ SYNTH=ltlk
+ case "$1" in
+ '[' '!' -d /etc/speakup ']'
+ '[' '!' -d /etc/speakup/ltlk ']'
+ cd /etc/speakup/ltlk
+ for f in '*'
+ '[' -w /sys/module/speakup/parameters/attrib_bleep
/sys/module/speakup/parameters/bell_pos
/sys/module/speakup/parameters/bleeps
/sys/module/speakup/parameters/bleep_time
/sys/module/speakup/parameters/caps_start
/sys/module/speakup/parameters/caps_stop
/sys/module/speakup/parameters/characters
/sys/module/speakup/parameters/chartab
/sys/module/speakup/parameters/cursor_time
/sys/module/speakup/parameters/delay_time
/sys/module/speakup/parameters/delimiters
/sys/module/speakup/parameters/ex_num
/sys/module/speakup/parameters/freq
/sys/module/speakup/parameters/full_time
/sys/module/speakup/parameters/jiffy_delta
/sys/module/speakup/parameters/key_echo
/sys/module/speakup/parameters/keymap
/sys/module/speakup/parameters/lang
/sys/module/speakup/parameters/no_interrupt
/sys/module/speakup/parameters/pitch
/sys/module/speakup/parameters/punc_all
/sys/module/speakup/parameters/punc_level
/sys/module/speakup/parameters/punc_most
/sys/module/speakup/parameters/punc_some
/sys/module/speakup/parameters/punct
/sys/module/speakup/parameters/quiet
/sys/module/speakup/parameters/rate
/sys/module/speakup/parameters/reading_punc
/sys/module/speakup/parameters/repeats
/sys/module/speakup/parameters/say_control
/sys/module/speakup/parameters/say_word_ctl
/sys/module/speakup/parameters/silent
/sys/module/speakup/parameters/spell_delay
/sys/module/speakup/parameters/synth
/sys/module/speakup/parameters/synth_direct
/sys/module/speakup/parameters/tone
/sys/module/speakup/parameters/trigger_time
/sys/module/speakup/parameters/version
/sys/module/speakup/parameters/voice
/sys/module/speakup/parameters/vol ']'
/usr/local/bin/speakupconf: line 43: [: too many arguments
Case 3: newline between asterisk and "do"
#!/bin/sh
set -x
# script to load/save all the vars in speakup
# speakupconf save or speakupconf load
# if root saves in /etc/speakup/<synth> else in $HOME/.speakup/<synth>
if [ $UID -eq "0" ]; then
SAVEDIR="/etc/speakup"
else
SAVEDIR="$HOME/.speakup"
fi
if [ ! -d /sys/module/speakup/parameters ]; then
echo "no directory /sys/module/speakup/parameters"
exit 0
fi
SYNTH=`cat /sys/module/speakup/parameters/synth`
case "$1" in
*save)
if [ ! -d $SAVEDIR ] ; then
echo creating $SAVEDIR
mkdir $SAVEDIR
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo creating $SAVEDIR/$SYNTH
mkdir $SAVEDIR/$SYNTH
fi
cd /sys/module/speakup/parameters
SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
for f in $SAVELIST; do
cp $f $SAVEDIR/$SYNTH/$f
done
;;
*load)
if [ ! -d $SAVEDIR ] ; then
echo no directory $SAVEDIR
exit 1
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo no directory $SAVEDIR/$SYNTH
exit 1
fi
cd $SAVEDIR/$SYNTH
for f in *
do
if [ -w /sys/module/speakup/parameters/$f ]; then
cat $f >/sys/module/speakup/parameters/$f
fi
done
;;
*)
echo "usage: speakupconf load/save"
exit 1
;;
esac
Results 3:
+ '[' 0 -eq 0 ']'
+ SAVEDIR=/etc/speakup
+ '[' '!' -d /sys/module/speakup/parameters ']'
++ cat /sys/module/speakup/parameters/synth
+ SYNTH=ltlk
+ case "$1" in
+ '[' '!' -d /etc/speakup ']'
+ '[' '!' -d /etc/speakup/ltlk ']'
+ cd /etc/speakup/ltlk
+ for f in '*'
+ '[' -w /sys/module/speakup/parameters/attrib_bleep
/sys/module/speakup/parameters/bell_pos
/sys/module/speakup/parameters/bleeps
/sys/module/speakup/parameters/bleep_time
/sys/module/speakup/parameters/caps_start
/sys/module/speakup/parameters/caps_stop
/sys/module/speakup/parameters/characters
/sys/module/speakup/parameters/chartab
/sys/module/speakup/parameters/cursor_time
/sys/module/speakup/parameters/delay_time
/sys/module/speakup/parameters/delimiters
/sys/module/speakup/parameters/ex_num
/sys/module/speakup/parameters/freq
/sys/module/speakup/parameters/full_time
/sys/module/speakup/parameters/jiffy_delta
/sys/module/speakup/parameters/key_echo
/sys/module/speakup/parameters/keymap
/sys/module/speakup/parameters/lang
/sys/module/speakup/parameters/no_interrupt
/sys/module/speakup/parameters/pitch
/sys/module/speakup/parameters/punc_all
/sys/module/speakup/parameters/punc_level
/sys/module/speakup/parameters/punc_most
/sys/module/speakup/parameters/punc_some
/sys/module/speakup/parameters/punct
/sys/module/speakup/parameters/quiet
/sys/module/speakup/parameters/rate
/sys/module/speakup/parameters/reading_punc
/sys/module/speakup/parameters/repeats
/sys/module/speakup/parameters/say_control
/sys/module/speakup/parameters/say_word_ctl
/sys/module/speakup/parameters/silent
/sys/module/speakup/parameters/spell_delay
/sys/module/speakup/parameters/synth
/sys/module/speakup/parameters/synth_direct
/sys/module/speakup/parameters/tone
/sys/module/speakup/parameters/trigger_time
/sys/module/speakup/parameters/version
/sys/module/speakup/parameters/voice
/sys/module/speakup/parameters/vol ']'
/usr/local/bin/speakupconf: line 44: [: too many arguments
Case 4: work around using ls
#!/bin/sh
set -x
# script to load/save all the vars in speakup
# speakupconf save or speakupconf load
# if root saves in /etc/speakup/<synth> else in $HOME/.speakup/<synth>
if [ $UID -eq "0" ]; then
SAVEDIR="/etc/speakup"
else
SAVEDIR="$HOME/.speakup"
fi
if [ ! -d /sys/module/speakup/parameters ]; then
echo "no directory /sys/module/speakup/parameters"
exit 0
fi
SYNTH=`cat /sys/module/speakup/parameters/synth`
case "$1" in
*save)
if [ ! -d $SAVEDIR ] ; then
echo creating $SAVEDIR
mkdir $SAVEDIR
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo creating $SAVEDIR/$SYNTH
mkdir $SAVEDIR/$SYNTH
fi
cd /sys/module/speakup/parameters
SAVELIST=` find . -perm -6 |sed 's/..//' |fgrep -v synth`
for f in $SAVELIST; do
cp $f $SAVEDIR/$SYNTH/$f
done
;;
*load)
if [ ! -d $SAVEDIR ] ; then
echo no directory $SAVEDIR
exit 1
fi
if [ ! -d $SAVEDIR/$SYNTH ] ; then
echo no directory $SAVEDIR/$SYNTH
exit 1
fi
cd $SAVEDIR/$SYNTH
for f in `ls -1 2>/dev/null`; do
if [ -w /sys/module/speakup/parameters/$f ]; then
cat $f >/sys/module/speakup/parameters/$f
fi
done
;;
*)
echo "usage: speakupconf load/save"
exit 1
;;
esac
Results 4:
+ '[' 0 -eq 0 ']'
+ SAVEDIR=/etc/speakup
+ '[' '!' -d /sys/module/speakup/parameters ']'
++ cat /sys/module/speakup/parameters/synth
+ SYNTH=ltlk
+ case "$1" in
+ '[' '!' -d /etc/speakup ']'
+ '[' '!' -d /etc/speakup/ltlk ']'
+ cd /etc/speakup/ltlk
++ ls -1
Note: Now the script works!
-- System Information:
Debian Release: 5.0
APT prefers testing
APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages bash depends on:
ii base-files 5 Debian base system miscellaneous f
ii debianutils 2.30 Miscellaneous utilities specific t
ii libc6 2.7-18 GNU C Library: Shared libraries
ii libncurses5 5.7+20081213-1 shared libraries for terminal hand
Versions of packages bash recommends:
pn bash-completion <none> (no description available)
Versions of packages bash suggests:
pn bash-doc <none> (no description available)
-- no debconf information
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]