Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Apr 2001 15:49:58 -0700
From:      Dima Dorfman <dima@unixfreak.org>
To:        Brian Somers <brian@Awfulhak.org>
Cc:        Garrett Wollman <wollman@khavrinen.lcs.mit.edu>, "John W. De Boskey" <jwd@bsdwins.com>, freebsd-standards@bostonradio.org, Mike Smith <msmith@freebsd.org>, current@freebsd.org, Jens Schweikhardt <schweikh@schweikhardt.net>
Subject:   Re: cp -d dir patch for review (or 'xargs'?) 
Message-ID:  <20010420224958.9763E3E09@bazooka.unixfreak.org>
In-Reply-To: <200104201911.f3KJB7540090@hak.lan.Awfulhak.org>; from brian@Awfulhak.org on "Fri, 20 Apr 2001 20:11:07 %2B0100"

next in thread | previous in thread | raw e-mail | index | archive | help
[ attempting to consolidate two identical threads into one ]

Brian Somers <brian@Awfulhak.org> writes:
> I agree - the script idea doesn't seem right.
> 
> If {} isn't allowed to implicitly mean ``all the arguments that'll 
> fit'', then I'd vote for using -i (a version that does full grouping) 
> although I would not vote for the semantics whereby -i must either be 
> followed directly with the replacement string (with no intervening 
> spaces) or else have an implicit {} replacement string, ie we should 
> have these meaning the same thing:
> 
>   xargs -i '<<<>>>' command blah '<<<>>>' blah
>   xargs -i'<<<>>>' command blah '<<<>>>' blah

I honestly don't understand the differnece between this and the -y
option gad described.  Nevertheless, it seems that pretty much
everyone agrees that something like this is a good idea.

Attached is a patch that adds a -Y option to xargs which does, well,
pretty much what I imagine the above would do.  Here are a couple of
examples:

	dima@spike% cat test		# test input
	this is just
	a test; it has
	no real purpose
	in life

	dima@spike% ./xargs -Y {} echo CMD LINE ARGS < test
	CMD LINE ARGS this is just a test; it has no real purpose in life

	dima@spike% ./xargs -Y {} echo {} CMD LINE ARGS < test
	this is just a test; it has no real purpose in life CMD LINE ARGS

	dima@spike% ./xargs -Y {} echo CMD {} LINE ARGS < test
	CMD this is just a test; it has no real purpose in life LINE ARGS

	dima@spike% ./xargs -Y {} echo CMD LINE {} ARGS < test
	CMD LINE this is just a test; it has no real purpose in life ARGS

	dima@spike% ./xargs -Y {} echo CMD LINE ARGS {} < test
	CMD LINE ARGS this is just a test; it has no real purpose in life

	dima@spike% ./xargs -n 2 -Y {} echo CMD LINE {} ARGS < test
	CMD LINE this is ARGS
	CMD LINE just a ARGS
	CMD LINE test; it ARGS
	CMD LINE has no ARGS
	CMD LINE real purpose ARGS
	CMD LINE in life ARGS

I'm not sure the patch is entirely correct.  xargs seems to be overly
complicated in the way it does some of its processing, but it works
and I believe I managed to maintain most of the assumptions it makes.

Comments?  Suggestions?

Thanks,

					Dima Dorfman
					dima@unixfreak.org

Index: xargs.c
===================================================================
RCS file: /st/src/FreeBSD/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.9
diff -u -r1.9 xargs.c
--- xargs.c	1999/08/28 01:07:50	1.9
+++ xargs.c	2001/04/20 22:37:15
@@ -73,6 +73,8 @@
 	int cnt, indouble, insingle, nargs, nflag, nline, xflag, wasquoted;
 	char **av, *argp, **ep = env;
 	long arg_max;
+	int apargs = 0;
+	char **avv, *replstr = NULL;
 
 	/*
 	 * POSIX.2 limits the exec line length to ARG_MAX - 2K.  Running that
@@ -96,7 +98,7 @@
 		nline -= strlen(*ep++) + 1 + sizeof(*ep);
 	}
 	nflag = xflag = wasquoted = 0;
-	while ((ch = getopt(argc, argv, "0n:s:tx")) != -1)
+	while ((ch = getopt(argc, argv, "0n:s:txY:")) != -1)
 		switch(ch) {
 		case 'n':
 			nflag = 1;
@@ -115,6 +117,9 @@
 		case '0':
 			zflag = 1;
 			break;
+		case 'Y':
+			replstr = optarg;
+			break;
 		case '?':
 		default:
 			usage();
@@ -144,6 +149,13 @@
 	else {
 		cnt = 0;
 		do {
+			if (replstr && strcmp(*argv, replstr) == 0) {
+				apargs = 1;
+				*argv++;
+				for (avv = argv; *avv; *avv++)
+					cnt += strlen(*avv) + 1;
+				break;
+			}
 			cnt += strlen(*bxp++ = *argv) + 1;
 		} while (*++argv);
 	}
@@ -211,6 +223,8 @@
 			if (xp == exp || p > ebp || ch == EOF) {
 				if (xflag && xp != exp && p > ebp)
 					errx(1, "insufficient space for arguments");
+				for (avv = argv; apargs && *avv; *avv++)
+					strlen(*xp++ = *avv) + 1;
 				*xp = NULL;
 				run(av);
 				if (ch == EOF)
@@ -253,6 +267,8 @@
 			if (xflag)
 				errx(1, "insufficient space for arguments");
 
+			for (avv = argv; apargs && *avv; *avv++)
+				strlen(*xp++ = *avv) + 1;
 			*xp = NULL;
 			run(av);
 			xp = bxp;


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010420224958.9763E3E09>