Newsgroups: comp.lang.perl
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!elroy.jpl.nasa.gov!jpl-devvax!lwall
From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall)
Subject: Re: Rank beginners question
Message-ID: <1991May2.182134.5661@jpl-devvax.jpl.nasa.gov>
Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall)
Organization: Jet Propulsion Laboratory, Pasadena, CA
References: <1991May2.173518.4194@cs.ucla.edu>
Date: Thu, 2 May 1991 18:21:34 GMT

In article <1991May2.173518.4194@cs.ucla.edu> frazier@oahu.cs.ucla.edu (Greg Frazier) writes:
: Hi-howdy -
: 	I am a beginner perl hack (obviously).  I am trying
: to get my script to manipulate some files in my directory.
: This works
: 	@foo = `ls *`;
: but this does not work
: 	@foo = `ls ~frazier`;
: the error msg is
: 	~frazier not found
: 
: I do not understand why the '*' gets expanded correctly but
: '~frazier' does not.  BTW, I am running cshell
: ($ENV{'SHELL'}=/bin/csh).  The man page for csh indicates that
: '*' and '~[username]' are both examples of filename expansion,
: so I would have assumed that if one was happening, the other
: would too.  I have tried various quotes and escapes to no
: avail:
: 	@foo = `ls '~frazier'`;
: 	@foo = `ls \~frazier`;
: 	@foo = `'ls ~frazier'`;
: 
: Any and all responses appreciated.  And, no, I do not want
: to use $ENV{`HOME`}, 'cuz I'd like other people to be able
: to run this script (and the files are in my directory).

You think you're running csh, but you're not.  All subshell commands
in Perl use /bin/sh, just as C's system() and popen() calls do.  To do
otherwise is to invite disaster.  You have three options:

1) Invoke csh explicity.  (Perl actually optimizes out the call to /bin/sh.)

	@foo = `/bin/csh -fc "ls ~frazier"`;

2) Use the glob syntax, which uses csh if available.

	@foo = <~frazier/*>;

3) Look up the home directory yourself.  This is portable to machines
without csh.

	$myhome = (getpwnam("frazier"))[7];
	@foo = `ls $myhome/*`;

or

	$myhome = (getpwnam("frazier"))[7];
	chdir $myhome;
	@foo = <*>;

Much faster would be

	$myhome = (getpwnam("frazier"))[7];
	opendir(DIR,$myhome);
	@foo = grep(/^\./, readdir(DIR));
	closedir(DIR);

Larry
