semicolon at beginning of line

2012-04-07 Thread Elliott Forney
I wish bash would happily execute lines that begin with a semicolon,
i.e., treat it as a no-op followed by a command.  The following
examples come to mind:

$ infloop& echo hello
[2] 11361
hello
$ infloop&; echo hello
bash: syntax error near unexpected token `;'

$ echo hello; echo world
hello
world
$ echo hello;; echo world
bash: syntax error near unexpected token `;;'

$ ; echo hello world
bash: syntax error near unexpected token `;'

Any thoughts?

Thanks,
  Elliott Forney



Re: semicolon at beginning of line

2012-04-09 Thread Elliott Forney
Sure, a comment can be used to place a line in your history but that
doesn't really address the examples I had.  Just seems to me like a
lone semicolon could be treated as a newline/noop.  I can't seem to
think of anything that this would break but, of course, that doesn't
mean it wouldn't.  The end of a case in a switch statement is
certainly an interesting one, hadn't thought of that, but it should be
possible to handle that by checking for ;; as a token before ;.

I might mention that ksh, zsh and tcsh all allow lines to begin with a
semicolon.  zsh even allows "; ; ; echo hello world ; ; ;" although
ksh only allows a single ; at the beginning of a line.

On Sun, Apr 8, 2012 at 6:48 PM, Joseph Fredette  wrote:
> Could also use a #, no?
>
> On Sun, Apr 8, 2012 at 8:46 PM, Steven W. Orr  wrote:
>
>> On 4/7/2012 4:00 PM, Elliott Forney wrote:
>>
>>> I wish bash would happily execute lines that begin with a semicolon,
>>> i.e., treat it as a no-op followed by a command.  The following
>>> examples come to mind:
>>>
>>> $ infloop&  echo hello
>>> [2] 11361
>>> hello
>>> $ infloop&; echo hello
>>> bash: syntax error near unexpected token `;'
>>>
>>> $ echo hello; echo world
>>> hello
>>> world
>>> $ echo hello;; echo world
>>> bash: syntax error near unexpected token `;;'
>>>
>>> $ ; echo hello world
>>> bash: syntax error near unexpected token `;'
>>>
>>> Any thoughts?
>>>
>>> Thanks,
>>>   Elliott Forney
>>>
>>
>> Just use a colon.
>>
>> : echo Hello world.
>>
>> I use it all the time to 'park' a command in my history. Then when I'm
>> ready, I just back up to it and remove the colon.
>>
>>
>> --
>> Time flies like the wind. Fruit flies like a banana. Stranger things have
>>  .0.
>> happened but none stranger than this. Does your driver's license say Organ
>> ..0
>> Donor?Black holes are where God divided by zero. Listen to me! We are all-
>> 000
>> individuals! What if this weren't a hypothetical question?
>> steveo at syslang.net
>>
>>



Re: semicolon at beginning of line

2012-04-09 Thread Elliott Forney
Here is another example that appears to defy my expectations.  In this
case, the semicolon is allowed:

sine:~$ hello='echo hello'
sine:~$ world='echo world'
sine:~$ ${hello};${world}
hello
world
sine:~$ unset hello
sine:~$ ${hello};${world}
world
sine:~$ unset world
sine:~$ ${hello};${world}

Thanks!
  Elliott Forney

On Mon, Apr 9, 2012 at 10:02 PM, Elliott Forney
 wrote:
> Sure, a comment can be used to place a line in your history but that
> doesn't really address the examples I had.  Just seems to me like a
> lone semicolon could be treated as a newline/noop.  I can't seem to
> think of anything that this would break but, of course, that doesn't
> mean it wouldn't.  The end of a case in a switch statement is
> certainly an interesting one, hadn't thought of that, but it should be
> possible to handle that by checking for ;; as a token before ;.
>
> I might mention that ksh, zsh and tcsh all allow lines to begin with a
> semicolon.  zsh even allows "; ; ; echo hello world ; ; ;" although
> ksh only allows a single ; at the beginning of a line.
>
> On Sun, Apr 8, 2012 at 6:48 PM, Joseph Fredette  wrote:
>> Could also use a #, no?
>>
>> On Sun, Apr 8, 2012 at 8:46 PM, Steven W. Orr  wrote:
>>
>>> On 4/7/2012 4:00 PM, Elliott Forney wrote:
>>>
>>>> I wish bash would happily execute lines that begin with a semicolon,
>>>> i.e., treat it as a no-op followed by a command.  The following
>>>> examples come to mind:
>>>>
>>>> $ infloop&  echo hello
>>>> [2] 11361
>>>> hello
>>>> $ infloop&; echo hello
>>>> bash: syntax error near unexpected token `;'
>>>>
>>>> $ echo hello; echo world
>>>> hello
>>>> world
>>>> $ echo hello;; echo world
>>>> bash: syntax error near unexpected token `;;'
>>>>
>>>> $ ; echo hello world
>>>> bash: syntax error near unexpected token `;'
>>>>
>>>> Any thoughts?
>>>>
>>>> Thanks,
>>>>   Elliott Forney
>>>>
>>>
>>> Just use a colon.
>>>
>>> : echo Hello world.
>>>
>>> I use it all the time to 'park' a command in my history. Then when I'm
>>> ready, I just back up to it and remove the colon.
>>>
>>>
>>> --
>>> Time flies like the wind. Fruit flies like a banana. Stranger things have
>>>  .0.
>>> happened but none stranger than this. Does your driver's license say Organ
>>> ..0
>>> Donor?Black holes are where God divided by zero. Listen to me! We are all-
>>> 000
>>> individuals! What if this weren't a hypothetical question?
>>> steveo at syslang.net
>>>
>>>



Thanks!

2012-04-09 Thread Elliott Forney
Also, I just wanted to send out a thanks to Chet Ramey and everyone
else that has contributed to bash.  I am a bash junkie and use it
every day.  Not only is bash my primary interactive shell, it is also
the scripting language that I write many of my programs in... and it
glues together many of the rest.

Thank you, you all rock!



Re: status on $[arith] for eval arith vsl $((arith))??

2012-04-09 Thread Elliott Forney
My two cents, would be to add a bit to the man page that says something like:

---
For historical reasons, the following format is also supported for
arithmetic evaluation:

$[expression]

Note, however, that this format is non-standard and that
$((expression)) is preferred.
---

At least that way there won't be an undocumented feature.

Thanks,
  Elliott Forney

On Mon, Apr 9, 2012 at 8:47 PM, Chet Ramey  wrote:
> On 4/9/12 9:07 PM, Linda Walsh wrote:
>>
>>
>> Maarten Billemont wrote:
>>
>>> Any particular reason for not removing old undocumented functionality,
>>> or is that mostly the nature of this beast - dragging along and maintaining
>>> ancient code for the sake of compatibility?
>
>>
>> So 'yesturday' is "ancient" for you?... that's really means something.
>
> You have a peculiar view of history (spelling and grammar, too, but we'll
> leave that aside).
>
>>
>> In doing a scan over my /usr partition,
>> I see MANY examples in bash 4.1 in it's examples of using $[] -- I would
>> hardly call 4.1 "ancient".
>
> True, I never went back and changed the examples.
>
>>
>>
>> Other packages that make use of the syntax:
>>
>> * wondershaper
>> * cifs file system
>> * alsa (sound)
>> * fonts-config   (this is a new project within the past few years)
>> * QT4
>> * GoogleBrowser (chromium)
>> * RPM
>> * YP
>> * PM Utils
>> * RPMrebuild
>> * iproute2 (almost all modern internet functions on linux)...
>> * dhcp-client
>> - (zsh -- not a real example, but might become alternate system shell if bash
>>  killed $[] support)
>> * Opera - ? (has comment "TODO use $(()) instead of $[] whenever
>> possible;...) "whenever possible??"
>> * samba
>>    and a HUGE number in
>> ** linux-kernel -- all over the place...
>>
>> At that point, I was getting too many to keep up with ... so I stopped
>> searching...
>>
>> $[] has is -- I would bet, Universally, used MORE than $(())...
>
> I believe you'd lose, but it's unprovable either way.  Consider the fact,
> though, that bash and zsh support $[...], ksh93 and dash support only
> $((...)), but that all four support $((...)).
>
>> Chet -- you should get back to the posix folks and tell them posix is to be
>> 'descriptive of usage' (their words), not prescriptive.   Just because ksh
>> did it differently from everyone else's usage doesn't mean they should go
>> with that syntax...
>
> You have got to be kidding.  Don't you realize you're talking about
> decisions that are nearly 20 years old?  That $[...] was a Posix
> invention that only ever appeared in P1003.2d9?  That the $((...))
> syntax was adopted officially for P1003.2-1992?  That's 1992.  Twenty
> years ago.
>
> Bash, and later zsh, implemented $[...] because there was no other
> syntax at the time, and to gain some operational experience with
> arithmetic expansion in the shell.  Bash-1.14 (the oldest I have
> readily available) lists both forms of arithmetic expansion, but by
> the time bash-2.0 was released in 1995, the manual referred only to
> the $((...)) form.  That's 17 years ago.  Hardly "yesterday".
>
> Now, it's hardly any problem to keep dragging the $[...] syntax along.
> It takes only a few dozen bytes of code.  I have no plans to remove it.
> But let's not kid ourselves: it's revisionist history to think that
> $[...] was widespread before Posix so callously stamped it out.
>
>> Geez.
>
> Indeed.
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                 ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRU    c...@case.edu    http://cnswww.cns.cwru.edu/~chet/
>



Re: semicolon at beginning of line

2012-04-10 Thread Elliott Forney
On Tue, Apr 10, 2012 at 1:22 AM, Maarten Billemont  wrote:
> People should stop trying to execute code by parameter expansion, and 
> specifically stop thinking that parameter-expanded words are evaluated as 
> bash code.

I still think the behavior is interesting.  The statement may not be
empty but nothing other than the expansion is executed.

> OK, so you're saying, let's change bash so that an empty statement becomes a 
> noop statement.

Yes.  It already is when a newline is received.  Why not when an empty
statement is terminated with a semicolon?

>Except for when that empty statement is preceded by a semicolon and happens to 
>have no whitespace, because then it could be a case delimiter.

Yes.  Just like "$(" differs from "$((" and "[" from "[[" and ">" from
">>".  This would not be unique syntax in bash.

> Frankly, what are you hoping to gain from this?

I simply believe it is intuitive; this is the behavior I would expect
before trying it.

> This will just introduce new rules with new exceptions and inconsistencies.  
> If it were possible to do a blanket rule: empty statements before a semicolon 
> are noops, I might be OK with it, but if it requires adding additional 
> addendums to the rule, "oh wait, except for this and that case", my vote is 
> out.

I really don't think it would cause lots of problems.  This belief is
supported by the fact that this is already implemented in other
shells.  Try the examples I have given in zsh and you will see the
behavior I would expect.  Try it in ksh and you will see something
closer to the blanket rule you suggest.

If no one else agrees then that's cool but my vote is to change it.

Thanks,
  Elliott Forney



Re: Parallelism a la make -j / GNU parallel

2012-05-03 Thread Elliott Forney
Here is a construct that I use sometimes... although you might wind up
waiting for the slowest job in each iteration of the loop:


maxiter=100
ncore=8

for iter in $(seq 1 $maxiter)
do
  startjob $iter &

  if (( (iter % $ncore) == 0 ))
  then
wait
  fi
done


On Thu, May 3, 2012 at 12:49 PM, Colin McEwan  wrote:
> Hi there,
>
> I don't know if this is anything that has ever been discussed or
> considered, but would be interested in any thoughts.
>
> I frequently find myself these days writing shell scripts, to run on
> multi-core machines, which could easily exploit lots of parallelism (eg. a
> batch of a hundred independent simulations).
>
> The basic parallelism construct of '&' for async execution is highly
> expressive, but it's not useful for this sort of use-case: starting up 100
> jobs at once will leave them competing, and lead to excessive context
> switching and paging.
>
> So for practical purposes, I find myself reaching for 'make -j' or GNU
> parallel, both of which destroy the expressiveness of the shell script as I
> have to redirect commands and parameters to Makefiles or stdout, and
> wrestle with appropriate levels of quoting.
>
> What I would really *like* would be an extension to the shell which
> implements the same sort of parallelism-limiting / 'process pooling' found
> in make or 'parallel' via an operator in the shell language, similar to '&'
> which has semantics of *possibly* continuing asynchronously (like '&') if
> system resources allow, or waiting for the process to complete (';').
>
> Any thoughts, anyone?
>
> Thanks!
>
> --
> C.
>
> https://plus.google.com/109211294311109803299
> https://www.facebook.com/mcewanca



wait unblocks before signals processed

2012-11-05 Thread Elliott Forney
While trying to modify some code I found on an earlier post for
running N jobs in parallel I came across the interesting behavior
illustrated below.  It appears that the wait command proceeds before
my SIGUSR's are all processed.  Is this a bug or just a fact of life?
I understand that it isn't possible to know if a process will receive
a signal in the future but I am surprised that the signals aren't
received and processed in time in this case.

On a related note, I think it would be very nice if there were a way
to wait for ANY background job to finish.  Currently it seems like one
can only wait for either ALL jobs or else a single job with a given
PID.  Would it be possible to have something like 'wait -' that would
block until any of the current background jobs completes?  This would
make writing simple parallel loops much easier.  The busy-wait/SIGUSR
solution is kindof a hack and for such a simple problem I would prefer
not to depend on gnu parallel.

#!/bin/bash

nrunning=0
nmax=3

function job_wrap
{
  echo "sleeping: $2 nrunning: $nrunning"
  eval "$@"
  kill -s USR2 $$
}

trap ': $(( --nrunning ))' USR2
for x in {1..20}
do
  while [[ nrunning -ge nmax ]]
  do
: # busy wait
  done

  : $(( ++nrunning ))
  job_wrap sleep $(( RANDOM % 3 )) &
done

echo 'start wait'
wait
trap - USR2
echo 'end wait'

$ ./par_sigusr
sleeping: 0 nrunning: 1
sleeping: 2 nrunning: 2
sleeping: 0 nrunning: 3
sleeping: 1 nrunning: 3
sleeping: 0 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 0 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 0 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 0 nrunning: 3
sleeping: 1 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 2 nrunning: 3
sleeping: 1 nrunning: 3
sleeping: 2 nrunning: 3
start wait
sleeping: 2 nrunning: 3
end wait
$ ./par_sigusr: line 10: kill: (16287) - No such process
./par_sigusr: line 10: kill: (16287) - No such process

Thanks!
---
Elliott Forney



Re: wait unblocks before signals processed

2012-11-05 Thread Elliott Forney
Of course, this code probably also has a race condition around
--nrunning which makes it even less usable.

Thanks,
---
Elliott ForneyE-Mail: id...@cs.colosetate.edu

On Mon, Nov 5, 2012 at 4:33 PM, Elliott Forney  wrote:
> While trying to modify some code I found on an earlier post for
> running N jobs in parallel I came across the interesting behavior
> illustrated below.  It appears that the wait command proceeds before
> my SIGUSR's are all processed.  Is this a bug or just a fact of life?
> I understand that it isn't possible to know if a process will receive
> a signal in the future but I am surprised that the signals aren't
> received and processed in time in this case.
>
> On a related note, I think it would be very nice if there were a way
> to wait for ANY background job to finish.  Currently it seems like one
> can only wait for either ALL jobs or else a single job with a given
> PID.  Would it be possible to have something like 'wait -' that would
> block until any of the current background jobs completes?  This would
> make writing simple parallel loops much easier.  The busy-wait/SIGUSR
> solution is kindof a hack and for such a simple problem I would prefer
> not to depend on gnu parallel.
>
> #!/bin/bash
>
> nrunning=0
> nmax=3
>
> function job_wrap
> {
>   echo "sleeping: $2 nrunning: $nrunning"
>   eval "$@"
>   kill -s USR2 $$
> }
>
> trap ': $(( --nrunning ))' USR2
> for x in {1..20}
> do
>   while [[ nrunning -ge nmax ]]
>   do
> : # busy wait
>   done
>
>   : $(( ++nrunning ))
>   job_wrap sleep $(( RANDOM % 3 )) &
> done
>
> echo 'start wait'
> wait
> trap - USR2
> echo 'end wait'
>
> $ ./par_sigusr
> sleeping: 0 nrunning: 1
> sleeping: 2 nrunning: 2
> sleeping: 0 nrunning: 3
> sleeping: 1 nrunning: 3
> sleeping: 0 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 0 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 0 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 0 nrunning: 3
> sleeping: 1 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 2 nrunning: 3
> sleeping: 1 nrunning: 3
> sleeping: 2 nrunning: 3
> start wait
> sleeping: 2 nrunning: 3
> end wait
> $ ./par_sigusr: line 10: kill: (16287) - No such process
> ./par_sigusr: line 10: kill: (16287) - No such process
>
> Thanks!
> ---
> Elliott Forney



Re: wait unblocks before signals processed

2012-11-05 Thread Elliott Forney
OK, I see in POSIX mode that a trap on SIGCHLD will cause wait to
unblock.  We are still maintaining a counter of running jobs though so
it seems to me that there could race condition in the following line

trap '((j--))' CHLD

if two processes quit in rapid succession and one trap gets preempted
in the middle of ((j--)) then the count may be off.  Is this possible?

I tried to test whether or not traps are mutually exclusive with the
following code and got more interesting warnings.  The count appears
to suggest that there is indeed a race condition going on here but I
am unsure what "bad value in trap_list" means?

#!/bin/bash

count=0

function dummy
{
  usleep $RANDOM
}

set -m
trap ': $(( ++count ))' CHLD

for i in {1..1000}
do
  dummy $i &
done

wait

echo $count


$ ./trap_race
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
./trap_race: warning: run_pending_traps: bad value in trap_list[17]: 0x4536e0
983

Thanks,
---
Elliott Forney


On Mon, Nov 5, 2012 at 5:11 PM, Dan Douglas  wrote:
> Hi Elliott. The behavior of wait differs depending upon whether you are in
> POSIX mode. Try this script, which I think does essentially what you're after
> (also here: https://gist.github.com/3911059 ):
>
> #!/usr/bin/env bash
>
> ${BASH_VERSION+shopt -s lastpipe extglob}
>
> if [[ -v .sh.version ]]; then
> builtin getconf
> function BASHPID.get {
> read -r .sh.value _  }
> fi
>
> function f {
> printf '%d: sleeping %d sec\n' "${@:1:2}" >&2
> sleep "$2"
>
> printf '%d: returning %d\n' "$1" "$3" >&2
> return "$3"
> }
>
> function main {
> typeset -i n= j= maxj=$(getconf _NPROCESSORS_ONLN)
>
> set -m
> trap '((j--))' CHLD
>
> while ((n++<30)); do
> f "$BASHPID" $(((RANDOM%5)+1)) $((RANDOM%2)) &
> ((++j >= maxj)) && POSIXLY_CORRECT= wait
> done
>
> echo 'finished, waiting for remaining jobs...' >&2
> wait
> }
>
> main "$@"
> echo
>
> # vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:
>
>
> The remaining issues are making it work in other shells (Bash in non-POSIX
> mode agrees with ksh, but ksh doesn't agree with POSIX), and also I can't
> think of a reasonable way to retrieve the exit statuses. The status of "wait"
> is rather useless here. Otherwise I think this is the best approach, using
> SIGCHLD and relying upon the POSIX wait behavior. See here:
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_11
>
> An issue to be aware of is that the trap will fire when any child exits
> including command/process substitutions or pipelines etc. If any are located
> within the main loop then monitor mode needs to be toggled off around them.
> --
> Dan Douglas



Re: wait unblocks before signals processed

2012-11-05 Thread Elliott Forney
> I believe that Bash guarantees the trap will run once for every child that
> exits, so it shoud be impossible for the count to become off. See:
> https://lists.gnu.org/archive/html/bug-bash/2012-05/msg00055.html

I guess my question is "can more than one trap run simultaneously?"
The more I think about it though, this is probably not possible.  It
looks like the trap doesn't run in a subprocess and I presume traps
are blocked inside of other traps.

> I think you might be experiencing other known bugs. Chet pushed several
> wait/job related commits within the last few weeks. I haven't tested these
> yet. http://git.savannah.gnu.org/cgit/bash.git/tree/CWRU/CWRU.chlog?h=devel

Sorry, I should look before posting.  I cloned the latest devel branch
of bash and now I see the following occasionally but it may still be a
work in progress.

$ ./trap_race
4.2.37(3)-maint
register_alloc: 0x9779a8 already in table as allocated?
register_alloc: 0x979378 already in table as allocated?
100

Thanks,
---
Elliott Forney



Re: wait unblocks before signals processed

2012-11-06 Thread Elliott Forney
Thanks!  If you run the sample script below you will see that the
development branch of bash occasionally crashes with an Aborted..
message too.

Do you have an opinion on having a variant of wait, say "wait -", that
will simply wait for any job to complete and return it's exit status?
I know that you probably have to be selective about what features you
spend time on but I would be curious what you think about the idea.
This feature would make it simple to solve these naive parallelization
problems without signals and traps.


#!/bin/bash

count=0

function dummy
{
  usleep $RANDOM
}

set -m
trap ': $(( ++count ))' CHLD

for i in {1..1000}
do
  dummy $i &
done

wait

echo $count

Thanks,
---
Elliott Forney

On Tue, Nov 6, 2012 at 11:30 AM, Chet Ramey  wrote:
> On 11/5/12 11:34 PM, Elliott Forney wrote:
>
>> Sorry, I should look before posting.  I cloned the latest devel branch
>> of bash and now I see the following occasionally but it may still be a
>> work in progress.
>>
>> $ ./trap_race
>> 4.2.37(3)-maint
>> register_alloc: 0x9779a8 already in table as allocated?
>> register_alloc: 0x979378 already in table as allocated?
>> 100
>
> That is a message from the debugging malloc that gets compiled in when
> you run a development build.  It is unrelated to any of the trap/wait
> changes, though it may indicate a possible memory leak.
>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



flag for quiet CDPATH

2014-01-20 Thread Elliott Forney
I find it a little unpleasant that cd echoes the new working directory
when CDPATH is used to locate the new directory (I already have the
working directory in my prompt).  I understand that this is behavior
is mandated by POSIX but I wonder if we could have an option that
disables this.

Maybe if the `cd' builtin had an option, say `-q', that would cause it
to be quit if CDPATH is used.  Then, I could simply

alias cd='cd -q'

and put a stop to this.  I have attached a proposed patch, any thoughts?

Thanks,
---
Elliott ForneyE-Mail: id...@cs.colostate.edu
Graduate Student  Phone:  1.402.215.7440
Computer Science Department   Web:http://www.cs.colostate.edu/~idfah
Colorado State University
diff -u builtins/cd.def.orig builtins/cd.def
--- builtins/cd.def.orig  2014-01-20 16:52:02.0 -0700
+++ builtins/cd.def 2014-01-20 16:37:17.0 -0700
@@ -92,6 +92,8 @@
  links
 -e if the -P option is supplied, and the current working directory
  cannot be determined successfully, exit with a non-zero status
+-q  prevent the working directory from being echoed when the
+  CDPATH variable is used to locate DIR
 
 The default is to follow symbolic links, as if `-L' were specified.
 
@@ -187,7 +189,7 @@
  WORD_LIST *list;
 {
   char *dirname, *cdpath, *path, *temp;
-  int path_index, no_symlinks, opt, lflag;
+  int path_index, no_symlinks, opt, lflag, qflag;
 
 #if defined (RESTRICTED_SHELL)
   if (restricted)
@@ -198,9 +200,10 @@
 #endif /* RESTRICTED_SHELL */
 
   eflag = 0;
+  qflag = 0;
   no_symlinks = no_symbolic_links;
   reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "LP")) != -1)
+  while ((opt = internal_getopt (list, "LPq")) != -1)
 {
   switch (opt)
  {
@@ -213,6 +216,9 @@
  case 'e':
eflag = 1;
break;
+ case 'q':
+   qflag = 1;
+   break;
  default:
builtin_usage ();
return (EXECUTION_FAILURE);
@@ -274,7 +280,7 @@
 is used to find the directory to change to, the new
 directory name is echoed to stdout, whether or not
 the shell is interactive. */
-   if (opt && (path = no_symlinks ? temp : the_current_working_directory))
+   if (opt && !qflag && (path = no_symlinks ? temp : the_current_working_directory))
printf ("%s\n", path);
 
free (temp);


Re: flag for quiet CDPATH

2014-01-20 Thread Elliott Forney
> +1 and `cd -' has the similar problem.

So, I guess there are several cases to consider.

1.  CDPATH
2.  cdable_vars
3.  -
4.  cdspell

I have attached another patch that would prevent echoing the path in
all of these cases with the `-q` option.
--- builtins/cd.def.orig	2014-01-20 16:52:02.0 -0700
+++ builtins/cd.def	2014-01-20 20:31:49.0 -0700
@@ -92,6 +92,8 @@
 	links
 -e	if the -P option is supplied, and the current working directory
 	cannot be determined successfully, exit with a non-zero status
+-q  prevent the working directory from being echoed when DIR
+	is found using - or CDPATH or spell correction or a variable name
 
 The default is to follow symbolic links, as if `-L' were specified.
 
@@ -187,7 +189,7 @@
  WORD_LIST *list;
 {
   char *dirname, *cdpath, *path, *temp;
-  int path_index, no_symlinks, opt, lflag;
+  int path_index, no_symlinks, opt, lflag, qflag;
 
 #if defined (RESTRICTED_SHELL)
   if (restricted)
@@ -198,9 +200,10 @@
 #endif /* RESTRICTED_SHELL */
 
   eflag = 0;
+  qflag = 0;
   no_symlinks = no_symbolic_links;
   reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "LP")) != -1)
+  while ((opt = internal_getopt (list, "LPq")) != -1)
 {
   switch (opt)
 	{
@@ -213,6 +216,9 @@
 	case 'e':
 	  eflag = 1;
 	  break;
+	case 'q':
+	  qflag = 1;
+	  break;
 	default:
 	  builtin_usage ();
 	  return (EXECUTION_FAILURE);
@@ -250,7 +256,7 @@
 #if 0
   lflag = interactive ? LCD_PRINTPATH : 0;
 #else
-  lflag = LCD_PRINTPATH;		/* According to SUSv3 */
+  lflag = qflag ? 0 : LCD_PRINTPATH;  /* According to SUSv3 */
 #endif
 }
   else if (absolute_pathname (list->word->word))
@@ -274,7 +280,7 @@
 		 is used to find the directory to change to, the new
 		 directory name is echoed to stdout, whether or not
 		 the shell is interactive. */
-	  if (opt && (path = no_symlinks ? temp : the_current_working_directory))
+	  if (opt && !qflag && (path = no_symlinks ? temp : the_current_working_directory))
 		printf ("%s\n", path);
 
 	  free (temp);
@@ -323,7 +329,8 @@
   temp = get_string_value (dirname);
   if (temp && change_to_directory (temp, no_symlinks))
 	{
-	  printf ("%s\n", temp);
+	  if (!qflag)
+	printf ("%s\n", temp);
 	  return (bindpwd (no_symlinks));
 	}
 }
@@ -336,7 +343,8 @@
   temp = dirspell (dirname);
   if (temp && change_to_directory (temp, no_symlinks))
 	{
-	  printf ("%s\n", temp);
+	  if (!qflag)
+	printf ("%s\n", temp);
 	  return (bindpwd (no_symlinks));
 	}
   else


Re: flag for quiet CDPATH

2014-01-21 Thread Elliott Forney
These are both good solutions, I was unaware of the builtin keyword or
that redirection could come before the command :)  Since cd doesn't
appear to print anything else to stdout I would probably support
leaving things as they are.

Thanks!