command substitutions in $PS4
Hello.
[tested on current git headf6d4def4e27b13fab174e948b94cd10550d3e10e]
Command substitution doesn't seem to work in $PS4 (used for xtrace prompt):
$ PS4='$(date +%T)> ' dash -xc : dash: 1: Syntax error: end of file unexpected (expecting ")")
And with the old syntax:
$ PS4='`date +%T`> ' dash -xc :
Quoted 1 line
:
And with more than one command:
$ PS4='`date +%T`> ' dash -xc ':;:'
Quoted 1 line
:
dash doesn't return and seems to go in a forking loop, presumably because the date there triggers another PS4 expansion and so on recursively
If I prevent the recursion with:
src/eval.c +8 -0
@@ -776,7 +776,15 @@ evalcommand(union node *cmd, int flags)int sep; out = &preverrout; + +/* +* reset xflag temporarily for command substitutions performed +* upon $PS4 expansion +*/ + xflag =0 ;outstr (expandstr (ps4val ()), out); + xflag =1 ; + sep =0 ; sep =eprintlist (out, varlist.list, sep);eprintlist (out, arglist.list, sep);
$ PS4='`date +%T`> ' ./src/dash -xc ':;sleep 1; date'
Quoted 1 line
:
21:43:47> sleep 1
21:43:48> date
Mon Nov 17 21:43:48 GMT 2014
The command substitution still fails upon the first expansion only. I quickly gave up trying to find out why as I found the code there hard to follow.
Signature · 1 line
Stephane
Quoted 45 lines · Stephane Chazelas
[tested on current git head
f6d4def4e27b13fab174e948b94cd10550d3e10e]Command substitution doesn't seem to work in $PS4 (used for xtrace prompt):
$ PS4='$(date +%T)> ' dash -xc : dash: 1: Syntax error: end of file unexpected (expecting ")")And with the old syntax:
$ PS4='`date +%T`> ' dash -xc :Quoted 1 line
:
And with more than one command:
$ PS4='`date +%T`> ' dash -xc ':;:'Quoted 1 line
:
dash doesn't return and seems to go in a forking loop, presumably because the
datethere triggers another PS4 expansion and so on recursivelyIf I prevent the recursion with:
src/eval.c +8
-0@@ -776,7 +776,15 @@ evalcommand(union node *cmd, int flags)int sep; out = &preverrout; + +/* +* reset xflag temporarily for command substitutions performed +* upon $PS4 expansion +*/ + xflag =0 ;outstr (expandstr (ps4val ()), out); + xflag =1 ; + sep =0 ; sep =eprintlist (out, varlist.list, sep);eprintlist (out, arglist.list, sep);$ PS4='`date +%T`> ' ./src/dash -xc ':;sleep 1; date'
Quoted 8 lines
Quoted 1 line
:
21:43:47> sleep 1
21:43:48> date
Mon Nov 17 21:43:48 GMT 2014The command substitution still fails upon the first expansion only. I quickly gave up trying to find out why as I found the code there hard to follow.
In FreeBSD sh, I have disabled command substitution in PS4 (POSIX does not require it anyway). It is treated as a syntax error.
Talking about syntax errors, dash has a problem there as well. If there is a syntax error in PS4 and set -x is enabled, it will not execute any simple commands (assignments to PS4 cause an error and are subsequently reverted). FreeBSD sh prints the error messages and subsequently uses the raw unexpanded text.
Signature · 1 line
Jilles Tjoelker