Bug#515234: bash fails to process files separately with for name in *

2009-05-10 Thread Drake Wilson
The traces you provide show that what's happening is actually that the
*, being expanded in a directory with no files, expands to the literal
'*', which is somewhat awkward with which to deal but which is
mandated by POSIX for /bin/sh:

From 
http://www.opengroup.org/onlinepubs/95399/utilities/xcu_chap02.html#tag_02_13,
retrieved on 2009-05-10:
| If the pattern contains an invalid bracket expression or does not
| match any existing filenames or pathnames, the pattern string shall
| be left unchanged.

So why are all these other filenames appearing in the trace?  Simple:
because you don't use the correct double-quoting around your use of
$f, and so

  [ -w /sys/module/speakup/parameters/$f ]

gets expanded to

  [ -w /sys/module/speakup/parameters/* ]

and then the * gets expanded in that context.  Note that this probably
means that the script is already broken in the case of filenames in
the starting directory that contain whitespace or pattern-matching
metacharacters.

   --- Drake Wilson



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#515234: bash fails to process files separately with for name in *

2009-02-14 Thread D. Curtis Willoughby
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