Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug#517008: alias not expanded with zsh -c



On Wed, 25 Mar 2009 16:30:08 +0000
Peter Stephenson <pws@xxxxxxx> wrote:
>Clint Adams wrote:
>>On Wed, Feb 25, 2009 at 03:28:50AM +0100, Vincent Lefevre wrote:
>>> Aliases are not expanded with the -c option, as shown below.
>>>
>>> vin% cmd=$(printf "emulate sh\nalias a='echo OK >&2'\na")
>>> vin% printf "%s\n" "$cmd"
>>> emulate sh
>>> alias a='echo OK >&2'
>>> a
>>> vin% printf "%s" "$cmd" | zsh -f
>>> OK
>>> vin% zsh -fc "$cmd"
>>> zsh:3: command not found: a
>>> vin% 
>>>
>>> There's no such problem with ksh93, bash in POSIX mode, and dash
>>> (pdksh has the same bug).
>>
>> That does appear to be the behavior.
>
> Yes, at least as far as native zsh mode goes this isn't a bug.

I should also have pointed out that the "emulate sh" doesn't make any
difference, it only takes effect after the string for -c has already been
parsed---it's basically the same issue as the alias expansion one itself.
You would need to start the shell in the appropriate mode.  I don't think
that's an unreasonable requirement.

Is the fix as simple as the following?  This is not a trick question, I
could very easily have missed something.

Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.100
diff -u -r1.100 init.c
--- Src/init.c	9 Mar 2009 15:57:59 -0000	1.100
+++ Src/init.c	25 Mar 2009 17:19:57 -0000
@@ -1038,9 +1038,32 @@
     if (cmd) {
 	if (SHIN >= 10)
 	    fclose(bshin);
-	SHIN = movefd(open("/dev/null", O_RDONLY | O_NOCTTY));
-	bshin = fdopen(SHIN, "r");
-	execstring(cmd, 0, 1);
+	if (isset(POSIXALIASES)) {
+	    /*
+	     * We need to process input one line at a time to
+	     * ensure aliases are available.
+	     */
+	    char *fil;
+	    int tempfd = gettempfile(NULL, 1, &fil);
+
+	    if (tempfd < 0) {
+		zerr("fc", "can't open temp file: %e", errno);
+		lastval = 1;
+	    } else {
+		int cmdlen;
+		unmetafy(cmd, &cmdlen);
+		write(tempfd, cmd, cmdlen);
+		lseek(tempfd, 0, SEEK_SET);
+		SHIN = tempfd;
+		bshin = fdopen(SHIN, "r");
+		loop(1, 0);
+	    }
+	    unlink(fil);
+	} else {
+	    SHIN = movefd(open("/dev/null", O_RDONLY | O_NOCTTY));
+	    bshin = fdopen(SHIN, "r");
+	    execstring(cmd, 0, 1);
+	}
 	stopmsg = 1;
 	zexit(lastval, 0);
     }
Index: Doc/Zsh/options.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v
retrieving revision 1.78
diff -u -r1.78 options.yo
--- Doc/Zsh/options.yo	3 Mar 2009 17:35:29 -0000	1.78
+++ Doc/Zsh/options.yo	25 Mar 2009 17:19:57 -0000
@@ -1719,6 +1719,20 @@
 ifnzman(noderef(Reserved Words))\
 ifzman(the section RESERVED WORDS in zmanref(zshmisc)).
 
+Another effect of this option, provided it is set at shell start up,
+is to cause the shell's tt(-c) option to save commands to a temporary file
+and read them line by line to ensure aliases are expanded.  For example,
+
+example(zsh -fc 'alias o="echo Hello"
+o')
+
+reports a `command not found' error, while
+
+example(zsh -o posixaliases -fc 'alias o="echo Hello"
+o')
+
+outputs `Hello'.
+
 Alias expansion takes place while text is being read; hence when this
 option is set it does not take effect until the end of any function or
 other piece of shell code evaluated as one unit.


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



Messages sorted by: Reverse Date, Date, Thread, Author