zsh-users
 help / color / mirror / code / Atom feed
* zsh detects rm * but not rm ** (multiple stars)
@ 2014-03-13  9:26 Amm
  2014-03-13 16:19 ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Amm @ 2014-03-13  9:26 UTC (permalink / raw)
  To: zsh-users

Hello,

I like this feature of zsh where it warns user when using
rm * or rm **/* (when RM_STAR_SILENT is not set)


But if by mistake I type rm ** OR for that matter rm **/**
it does not detect this and does not warn!


BOOM!! Everything will be erased in 2nd case!!
(I know there is still -i to save me!)


But I suppose match should not just be on single *
but on *+ (1 or more *)

Please consider this.


Also is there a way to make zsh warn when there is * in
argument list, regardless of command?

i.e. it should warn me even if I type:

$ cp * /abcd/

zsh: sure you want to pass all the files in ... [yn]?

Is this possible?


Thanks and regards,


Amm



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zsh detects rm * but not rm ** (multiple stars)
  2014-03-13  9:26 zsh detects rm * but not rm ** (multiple stars) Amm
@ 2014-03-13 16:19 ` Bart Schaefer
  2014-03-14  5:48   ` Amm
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2014-03-13 16:19 UTC (permalink / raw)
  To: zsh-users

On Mar 13,  5:26pm, Amm wrote:
} Subject: zsh detects rm * but not rm ** (multiple stars)
}
} But I suppose match should not just be on single *
} but on *+ (1 or more *)

Thanks for the suggestion.  The "rm *" behavior is very old (was in
the shell even before the special meaning of "**", something over 20
years ago now) and hasn't changed in all that time, so I can't say
with any confidence it'll change now.  It probably wouldn't have been
included in the first place if the shell then had some of the other
features that have been added since.
 
} Also is there a way to make zsh warn when there is * in
} argument list, regardless of command?

I think most people would just find this annoying :-) and it's hard
to emit a sensible prompt when you don't know what's going to be done
with the result.  However:

zle-line-finish() {
  emulate -R zsh -o extendedglob -o localoptions
  local words stars ask yes
  words=( ${(Z{c})BUFFER} )
  [[ -o interactivecomments ]] && words=( ${words%(#s)\#*} )
  stars=( ${(M)words#((#s)[*]|*/[*]##)(#e)} )
  for ask in $stars
  do
    read -q yes$'?\n'"zsh: sure you want to pass $ask [n/y]?"
    if [[ $yes != y ]]
    then
      zle -I
      zle push-input
      zle send-break
    fi
  done
  (( $#stars )) && zle -I
}
zle -N zle-line-finish

This behaves the way you wanted, aborting the entire command on any
"no" answer (but leaving it in the editor for you to fix, which you
didn't ask for but seemed reasonable).

The placement of "zle -I" here is critical for reasons that are most
likely a bug.

-- 
Barton E. Schaefer


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zsh detects rm * but not rm ** (multiple stars)
  2014-03-13 16:19 ` Bart Schaefer
@ 2014-03-14  5:48   ` Amm
  2014-03-14  6:02     ` Amm
  0 siblings, 1 reply; 4+ messages in thread
From: Amm @ 2014-03-14  5:48 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 1872 bytes --]


On 03/13/2014 09:49 PM, Bart Schaefer wrote:

> On Mar 13,  5:26pm, Amm wrote:
> } Subject: zsh detects rm * but not rm ** (multiple stars)
> }
> } But I suppose match should not just be on single *
> } but on *+ (1 or more *)
>
> Thanks for the suggestion.  The "rm *" behavior is very old (was in
> the shell even before the special meaning of "**", something over 20
> years ago now) and hasn't changed in all that time, so I can't say
> with any confidence it'll change now.

Umm, I think it should be changed.

I have tried to fix this. I have attached a patch to exec.c file,

Patch is very small. It does not change logic. Just extends the check to 
checkriskyglob() function.

Currently checkriskyglob() checks for glob containing / and *.

So it will match / OR */ OR **/  OR */* OR **/* OR **/** so on

In future it may be extended to check other patterns which can cause 
accidental destruction.


>
> } Also is there a way to make zsh warn when there is * in
> } argument list, regardless of command?
>
> I think most people would just find this annoying :-)


I doubt it would be annoying because:

1) I dont think good administrator would ever use * directly for any 
command (Its better to be very specific by simply pressing *<TAB> - 
which will expand star to ALL files)

2) If one still feels annoyed then just like RM_STAR_SILENT|WAIT we can 
add CMD_STAR_SILENT/WAIT.

Only difference is that CMD_STAR_SILENT would be enabled by default and 
CMD_STAR_WAIT would be disabled by default.

So existing behaviour will continue by default but anyone who wants 
functionality I wanted, can activate accordingly.


> This behaves the way you wanted, aborting the entire command on any
> "no" answer (but leaving it in the editor for you to fix, which you
> didn't ask for but seemed reasonable).

Great thanks a lot. You have always been of great help.

Amm

[-- Attachment #2: rmriskyglob.c.patch --]
[-- Type: text/x-patch, Size: 1111 bytes --]

--- exec.c.old	2014-03-14 10:31:32.071645866 +0530
+++ exec.c	2014-03-14 10:53:35.616798543 +0530
@@ -2351,6 +2351,18 @@
 }
 
 /**/
+static int
+checkriskyglob(const char *s)
+{
+    if (!s) return 0;
+    while (s[0] == Star || s[0] == '/') {
+        if (!s[1]) return 1;
+        ++s;
+    } 
+    return 0;
+}
+
+/**/
 static void
 execcmd(Estate state, int input, int output, int how, int last1)
 {
@@ -2729,20 +2741,18 @@
 	LinkNode node, next;
 
 	for (node = nextnode(firstnode(args)); node && !errflag; node = next) {
-	    char *s = (char *) getdata(node);
+	    char *rs, *s = (char *) getdata(node);
 	    int l = strlen(s);
 
 	    next = nextnode(node);
-	    if (s[0] == Star && !s[1]) {
+	    if (checkriskyglob(s)) {
 		if (!checkrmall(pwd))
 		    uremnode(args, node);
-	    } else if (l > 2 && s[l - 2] == '/' && s[l - 1] == Star) {
-		char t = s[l - 2];
-
-		s[l - 2] = 0;
+	    } else if (l > 2 && (rs = strrchr(l, '/')) && checkriskyglob(rs+1)) {
+		*rs = 0;
 		if (!checkrmall(s))
 		    uremnode(args, node);
-		s[l - 2] = t;
+		*rs = '/';
 	    }
 	}
 	if (!nextnode(firstnode(args)))

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: zsh detects rm * but not rm ** (multiple stars)
  2014-03-14  5:48   ` Amm
@ 2014-03-14  6:02     ` Amm
  0 siblings, 0 replies; 4+ messages in thread
From: Amm @ 2014-03-14  6:02 UTC (permalink / raw)
  To: zsh-users



On 03/14/2014 11:18 AM, Amm wrote:
>
> I have tried to fix this. I have attached a patch to exec.c file,

In the patch please correct

(rs = strrchr(l, '/')) to
(rs = strrchr(s, '/'))

Amm.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-03-14  6:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-13  9:26 zsh detects rm * but not rm ** (multiple stars) Amm
2014-03-13 16:19 ` Bart Schaefer
2014-03-14  5:48   ` Amm
2014-03-14  6:02     ` Amm

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).