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

Re: script line not working as its supposed to, but why?



On Wed, Dec 11, 2013 at 01:44:51PM +0000, Sharon Kimble wrote:
> On Wed, 11 Dec 2013 12:42:51 +0100
> "Gian Uberto Lauri" <saint@eng.it> wrote:
> 
> > Sharon Kimble writes:
> >  > But there is no consistency with the creation date, the menu
> >  > itself is regenerated whenever I install a new programme, and the
> >  > old menu is saved with the suffix of the date and time.
> > 
> >  > I want to delete the 'menu-*' files if there are more than 7, and
> >  > the command is parsed when I have 'set -x' at the head of the
> >  > script but this line does nothing! It runs but doesn't achieve
> >  > anything.
> > 
> > The find command is not your friend here, I think.
> > 
> > If you have a single directory where these menu are regenerated
> > automatically, you could exploit the fact that lines like
> > 
> > menu-20131209-11:05
> > 
> > have an asciibetic order (order based on the ASCII code) that matches
> > the age order, but reversed, I mean newer backups come last. The
> > option -t of ls fixes this.
> > 
> > I would try with something like this:
> > 
> > if [  `ls -1 menu-* | wc -l` -gt 7 ]
> > then
> >     ls -t menu-* | tail $((7-`ls | wc -l`)) | xargs rm
> > fi
> > 
> > The first test ensures that you have more than 7 files.
> > 
> > Then you list the files in reverse asciibetical order (that is older
> > last), then the expression
> > 
> > $((7-`ls | wc -l`))
> > 
> > does the magic to compute the option to pass to tail so that it shows
> > the last (number of files - 7). And finally xargs feeds rm. You can
> > use rm -v to see them being deleted :)
> > 
> > I hope this helps.
> > 
> Thanks for this, I've just got round to testing it. I pasted it into my
> bigger script which works as expected, and then it came to your lines
> of code, and this is its output from it -
> 
> ++ wc -l
> ++ ls -1 'menu-*'
> ls: cannot access menu-*: No such file or directory
> + '[' 0 -gt 7 ']'

I think your problem here is to do with "globbing". If you look at
Gian's example, it has:

  $ ls -1 menu-*

whereas yours has:

  $ ls -1 'menu-*'

i.e. the filename is in single quotes. In the first case, the parameter
"menu-*" is seen by the shell as a wildcard parameter. Before execution
of "ls", bash will read the directory and find all files that match that
pattern and pass those filenames to the command. In other words, ls
actually sees the parameters "-1", "menu-2011...", "menu-2012..." and so
on. Several filenames, all of which exist.

In the second case, the last parameter is a literal string. By putting
the parameter in quotes, you're protecting it from shell expansion. "ls"
sees only two parameters in this case: "-1" and then "menu-*". "ls"
DOESN'T do parameter expansion itself, so it tries to list the file
called "menu-*". This file doesn't exist, so you get the above error.

As an aside, if you want to use a parameter and are worried about the
parser not knowing where the parameter name starts and ends, use ${}.
For example, if I have a parameter $x and I want to echo the contents of
that immediately followed by the letter y, I'd say "echo ${x}y". ${x} is
essentially the same as $x, but shows the parser where to start and end.

Hope that all helps.

Attachment: signature.asc
Description: Digital signature


Reply to: