This command results in:
echo -- -n
-- -n
I ended up doing
echo a-n|sed s/a//
Do I send the patch, do you consider this a bug?.
--
- curiosity sKilled the cat
-rob
{echo -n -n; echo}
But again, why not
echo -- -n
?
because we do gnot like that sort of stuff.
Plan 9 is not UNIX.
The difference in code is:
<
< if(argc > 1)
< if(strcmp(argv[1], "--") == 0){
< argv++;
< argc--;
< }
< else if(strcmp(argv[1], "-n") == 0)
< nflag = 1;
---
> if(argc > 1 && strcmp(argv[1], "-n") == 0)
> nflag = 1;
Which is not much.
So, my question remains, why not?. Even in the UPE it says that
the echo -n '
'
is ugly...
Followed by <http://9fans.net/archive/2001/09/54>.
--Joel
rm -- -r whynot
rm: -r: '-r' file does not exist
rm: whaynot: 'whaynot' file does not exist
…At this point the Plan 9 realized history repeating itself, and
although she did not want to offend either, she decided it was better
to offend the impatient youth rather than subject all her suitors to
yet another surfeit of notation.
—From "Plan 9 and the Echo, with apologies to Doug McIlroy" by Russ
Cox, linked to in my previous post.
Except, this is a different kind of problem.
The file talks about
echo ''
which I understand should not be fixed because breaks other things and
is a general case (as Russ points) of the question "what should we
do when given an empty string / 0 size write etc." which is tricky
and complicated.
echo -- -n
is a different kind of issue I think. I would just want to be told the
reason(s) behind this.
The fix doesn't break anything, makes echo consistent with the rest of
programs and consists of two clear and simple lines of code.
I wasn't trying to flame (originally, then I got carried away). I am
just curious
why this wasn't fixed.
you could also echo ' -n' if the output can deal with a spurious
space. or echo -n -n;echo
this is a very odd case which can be worked around without adding --.
the adding of which adds another odd case. what if you want to echo
--? so adding -- special case code doesn't really solve any problems.
an interesting question may be, why isn't "echo -n" a seperate program.
in any event, i think this ship has sailed.
- erik
> --? so adding -- special case code doesn't really solve any problems.
echo -- --?
odd but important. it's worth knowing that
x=`{read}
echo $x
can transform more than just white space.
personally, i'd vote for allowing -- just for
the above case: echoing unknown text.
the first argument to echo is not always a known constant.
FWIW,
echo '' $x
will often be sufficient, if the output ignores leading white space.
what's your reasoning that this is an important case?
- erik
#include <u.h>
#include <libc.h>
/* echo: echo args */
void
main(int argc, char *argv[])
{
int nl = 1;
ARGBEGIN{
'n':
nl = 0;
break;
default:
fprint(2, "usage: echo [-n] stuff\n");
sysfatal("usage");
}ARGEND;
for(i = 1; i < argc - 1; i++)
print("%s ", argv[i]);
print("%s%s", argv[argc - 1], nl ? "\n" : "");
exits(0);
}
However, Plan 9 has gone for years and people have not had this
problem. (Then again, so did TUPE for Unix).
Can we stick with
echo -n '-n
'
as Rob (the coauthor of that book, mind you, so he knows EXACTLY what
he is saying) said? It defies the need for handing a single argument.
If we start supporting arguments, we can have other arguments:
-e Use escape sequences.
-E Use no escape sequences.
-l (ell) One per line.
-t Separate with tabs.
-Nn Use n spaces (default 1).
-L If -l is given, use line numbers.
-o Output each character in octal.
-x Output each character in hex.
-v Make non-printing characters visible.
-r The first argument is a regular expression. Print each string
given as an argument that matches this regular expression.
and no doubt people will want them. Is this necessary? echo -e is
considered harmful (and when I started /bin/sh programming, I didn't
like that it wasn't default. Oh well).
The lesson?
echo -n '-n
'
is the solution.
I'm leaning toward Eric's suggestion of splitting echo in twain. When
facing south, the Plan 9 will open her mouth to echo nothing; when
facing north (echo-n or echon or something) she won't.
--Joel
And in any case, the "do the same thing the same way
all the times" argument suggests that -- should terminate
option processing. doesn't it?
echo does not interpret -- to mean the end of options.
This is just a matter of the proper behavior to implement echo -- with.
Using two programs is the approach that "Program Design in the Unix
Environment" suggests taking in a time like this, but it breaks
compatibility with previous versions of echo.
There is no solution. Let us not forget:
values of Δ will give rise to doom!
at least get that one right, please?
i think it's important because every time you put
echo $foo in a shell script, you're opening yourself
to unexpected behaviour should the first member of $foo
happen to become -n at some time.
the possibility of a security hole via this mechanism is small
but present (try grep 'echo[ ]+\$' /rc/bin/*)
one can always do:
echo -n $"foo^'
'
i suppose, but i doubt that anyone ever will.
mind you, it's a lot better than interpreting backslash escapes a la sys v echo.
>> values of Δ will give rise to doom!
>
> at least get that one right, please?
You don't get it, do you?
Δ is the symbol for change.
Now do you get it?
CHANGE ---> DOOM
I know this is a silly question, but doesn't this defeats the purpose
of the first -n?
iru
despite being quite the little tard, i'll give you a pass. what you
quoted incorrectly is this:
9grid% sed -n 88,91p /usr/andrey/unix/V6/usr/source/s2/mv.c
if(*--argp1 == '.'){
write(1,"values of B will give rise to dom!\n",37);
exit();
}
9grid%
description here: http://cm.bell-labs.com/cm/cs/who/dmr/odd.html
We need to keep echo the same because of the fact we can't agree on
something.
what makes you think agreeing with you is of any relevance?
iru
see, even facing this percentage of futileness, you haven't bothered
yourself to think what are you doing here.
iru
yes
so is any of the other solutions, each with its own constraints.
> with a different implementation it might as well
> complaint that '
> ' is an invalid flag.
no. This breaks unnecesarily:
echo -a
-a
which is useful.
The kind of change I was suggesting was minimal. Just solved the problem
did not break anything else. The only thing it could have potentialy
break was
echo --
which before wrote
--
and now writes only the newline.
This could be easily solved by rewriting it as
echo -- --
and I haven't seen any instance of this in /rc/bin (I looked even
if it was not very carefully).
The benefits of the change are easy to see. If you write
echo -- anything
you know the anything is now being echoed, whatever that is.
>
> And in any case, the "do the same thing the same way
> all the times" argument suggests that -- should terminate
> option processing. doesn't it?
>
Yes, it is probably true that another "if" to ignore -- after the -n could
be added. I wrote it just as an example of how little change would be
needed. The complete change to do it "right" would be again:
(written as an example, untried and not being overly careful)
#include <u.h>
#include <libc.h>
void
main(int argc, char *argv[])
{
int nflag, argi;
int i, len;
char *buf, *p;
nflag = 0;
argi = 0;
if(argc > 1)
if(strcmp(argv[1], "--") == 0)
argi++;
else if(strcmp(argv[1], "-n") == 0){
nflag++;
argi++;
if(argc > 2 && strcmp(argv[2], "--") == 0)
argi++;
}
len = 1;
for(i = 1+argi; i < argc; i++)
len += strlen(argv[i])+1;
buf = malloc(len);
if(buf == 0)
exits("no memory");
p = buf;
for(i = 1+argi; i < argc; i++){
strcpy(p, argv[i]);
p += strlen(p);
if(i < argc-1)
*p++ = ' ';
}
if(!nflag)
*p++ = '\n';
if(write(1, buf, p-buf) < 0)
fprint(2, "echo: write error: %r\n");
exits((char *)0);
#include <u.h>
#include <libc.h>
void
main(int argc, char *argv[])
{
int nflag, argi;
int i, len;
char *buf, *p;
nflag = 0;
argi = 0;
for(i = 1; i < argc; i++){
if(argv[i][0] != '-' )
break;
if (strcmp(argv[i], "--") == 0){
argi++;
break;
}
if(strcmp(argv[i], "-n") == 0){
argi++;
nflag++;
Two echo programs, with no options, would be less code. And then we
could all go back to complaining about the lack of OpenOffice.org and
Java. :)
--Joel
Who needs OpenOffice.org Calc when you have CSV and awk?
Who needs OpenOffice.org Impress (PowerPoint) when you have troff and
either mv or Uriel's macros?
Who needs OpenOffice.org Draw when you have 2nd edition draw in /n/
sources/extra?
Who needs OpenOffice.org Base when you have PQ (which I have not tried)?
(I have been considering writing a database for Plan 9 that uses
distributed computing and possibly 9P.)
Who needs Java when you have Inferno and Limbo and Dis?
This is what I love about this list. It's sooo relevant to system software.
It's supposed to be fun!
brucee
brucee
Pietro, as usual you have missed the important part--in this case, the
humor. I'm pretty sure Joel knows all those things you've listed
better than you do yourself.
Your replacements are pretty questionable, too.
Write is basically crap. I gnash my teeth with a great anger every
time I use it; my roommate was rather concerned a few years ago when
OO dumped about a half hour's hard work on a lab report and I punched
my bedframe as hard as possible... I think he feared for his life, OO
made me that angry. However, having done basic things like format
text, add images, and insert tables in both Write and troff, Write is
much simpler, although I think troff does a better job. I could
actually consider replacing Write with troff or maybe TeX if it comes
down to it.
CSV and awk? I like awk, and CSV is fine, but if I could choose one
program to have on Plan 9, a decent spreadsheet would be pretty high
up on the list; it's the original Killer App and quite convenient for
a lot of quick, simple tasks that become less quick and simple when
you do them almost any other way.
While I dislike PowerPoint and think that people could do well to use
fewer slides, we're stuck with them for now; strangely, when you're
collaborating on a project, others aren't always thrilled when you
tell them they need to learn a typesetting language before working on
the slideshow. The number of .ppt files I've been mailed over the
last couple years... pretty steep.
Comparing Draw to the 2nd edition 'art' is rather silly. I don't
think I need to go deeper.
I haven't used PQ either. In fact, has anyone used PQ in the last
couple years? I wouldn't trust OO to do my databases, but considering
the Sinkhole of Support I'd be likely to experience with PQ (it's in
sources/extra, it's old, it's unsupported), I'd be more inclined to
write an interface to a remote postgresql or MySQL server, or try to
port one of those.
I agree with you 100% on the last point, though. Nobody needs Java,
and nobody knows that better than the people on this list.
John
while databases aren't in the unix/plan 9 cannon, i've had jobs
where we really did have a database of users, groups, subscriptions,
searches, documents, document collections and collection groups.
foreign keys a go go. (mysql need not apply.)
on a small scale, this is plenty managable in a traditional filesystem.
when you need to track ~30 million documents and a couple hundred
million searches while insert rows in multiple tables transactionally,
a real database is awful nice.
while it would be nice to have a beefy plan 9 database, i wouldn't
bother porting one even if i needed it. why not figure out what the
client protocol is and implement that for plan 9?
- erik
The DBMS is a 9P server. Upon mounting, it takes as arguments two files:
- the list of names of records and fields
- the data itself
It then parses the data into virtual files in the location given with
the mount command.
For example, let's say I have a customer database for a kitchenware
distributor stored in two files: customer_fields (the list of field
and record names) and customer_data. I can load it with:
9dbms
mount /srv/9dbms /n/customers customer_fields customer_data
If that's not possible, these two filenames are stored in another file.
Now here's what this /n/customers will have. If the fields file looks
like this:
!record:uvlong # records are numbered
name:string * 1
address:string * 2
phoneno:string[10]
wants:list of string
and we have customers numbered 4, 9, and 30:
cpu% cd /n/database
cpu% ls
4
9
30
cpu% ls 4
name
address
phoneno
wants
cpu% cat 4/wants
3 of 30-inch deep pots
4 sets of 20 Imperial-grade steel forks
cpu%
You see what's going on? The use of 9P means there will be NO special
API for accessing the database: you just use open, read, write, &c,
or rc and the standard tools. This makes report generation a breeze:
#!/bin/rc
rfork e
cd /n/database
{
echo '.DS'
for(i in *){
cat $i/name
cat $i/address
cat $i/phoneno
echo 'REQUESTS:
cat $i/wants
echo
}
echo '.DE'
} | troff -ms
Or, for a more elaborate report:
#!/bin/rc
rfork e
cd /n/database
{
cat <<\END
.TS
center;
c s
lfB lfB lfB lfB
l l l l.
\fBREPORT\fP
Name Address Phone Number Wants
END
for(i in *){
cd $i
name=`{cat name}
addr=`{cat address}
pn=`{cat phoneno}
echo $"name^' '^$"addr^' '^$"pn^' T{'
cat wants
echo 'T}'
cd ..
}
} | tbl | troff -ms
Then, if you use bitsy, you can write a program with libcontrol and
the networking commands to make a portable remote customer editor!
Yes. In the past few years I've worked with teams building two
unrelated applications with it. One went through a technology
trial with a Tier 1 US telecom provider, but then floundered for
unrelated reasons. The other was, for years, responsible for
moving several millions of dollars around every month between
a few hundred global GSM operators. The company has since
been sold; the buying company initially decided on using our
platform to replace theirs, but then everyone I knew there left,
so I can't comment on current state. The web site for the
service is at least unchanged.
Sadly, both those projects relied on an update mechanism which
was a proprietary extention not included in the distribution.
Getting a good update mechanism that fits well with the
distrubuted version has been an ongoing challenge.
The official directory folks at ALU were, at least until shortly
after the merger, using it as a front end for an assortment of
proprietary HR-type systems. I believe that was dying out,
although I can't say as the folks I knew there have since gone
over to at&t. That group's version was an evolutionary cousin
of the Plan 9 one.
I'm also using it on a personal project, and am working on
updating the distrubution, in part in response to second-hand
requests from some folks who want to update an application
using (almost exactly) the Plan 9 version on Solaris.
So, yes. It's probably a single-digit number of active projects
and double-digit user base (not counting users of the services
these applications provide, in which case it's at least single-
digit thousands), but non-zero.
Anthony
The problem is that the application talking to the database
still has to know too much about the representation, making it
fairly static. This isn't inherently a problem, really, but it isn't
anything resembling a relational (or, since pq was mentioned,
implicit relational) database.
One could certainly do an on-the-fly generated namespace in
response to each query. That'd be neat for interactive use, but,
again, any real application using it would have to already know
a lot about the structure of what it's getting back. Given that,
getting the database out of a file tree isn't really a win over
getting it out of a tab-separated text line (or whatever your
DB gives you).
Two related things I think *are* more interesting. First, I've
often found it useful to have a "middleman" application
turning a more general backing store into a more structured
file tree. This is, for example, how Inferno's styx-on-a-brick
demo worked: each layer in the stack provided a different
file tree with more structure imposed (okay, it was a short
stack). This allows you to avoid stuffing too many of the
specifics into what should be more general.
Second, and really more simply, we've found it useful to
have a channel to the database present in the file system.
Eliminate any network programming from your apps, and if
the app providing the channel does a good job, you get a set
of benifits more or less for free (or at least for aggregated cost).
Anthony
Any change in externally visible behavior could in principle
"break something" that had relied on the previous behavior.
That said, "echo" has historically been a problem since
without support for option arguments it is too limited,
but with support for option arguments one has to worry
about accidental options, as in the original question. With
incomplete support for option arguments it is just confusing.
I got disgusted enough with the variety among versions of
"echo" that impacted upon otherwise portable shell scripts
that I designed my own version that supports the Unix
command syntax standard, is flexible enough to provide
all the useful option behavior modifications (including
optionally enabling embedded \-escapes), and can be
"aliased" to any of the usual flavors of "echo" by including
thright combination of options in the prefix. I named it
"gecho" (for "generic", not "GNU") and can provide specs
and/or implementation upon request.
Who needs an operating system when you have a 0 and a 1?
Russ
Exactly.
echo -- {whatever} # {whatever} can be "--", "-n", or other things
Is that a pointer to const volatile?
Actually all you need is one symbol.
3(decimal) = |||
7(decimal) = |||||||
etc. Obviously this can express any numerically-coded object.
No, but all my base are belong to you.
whatever | echo 0 > /srv/whatever
I mean, how can you pipe to echo? So I have a fixed version.
Now, the sequence above will check fd 0 in the namespace. If it is a
pipe, it will copy fd 0 to fd 1 until EOF, or the rent is due.
Further, I added these patches to echo:
abcdefghijklmnopqv
v works as on cat. All other switches, see the texinfo.
ron
How are you going to call it smacmeecho ?.
NAME
echo: echo arguments
SYNOPSIS
echo [-1abCDEeilmNnOqrtuVvwXx] [-B base] [-c cmd] [-d char] [-f
file] [-L len] [-o file] [-S voice] [-s char] [args...]
DESCRIPTION
echo outputs its arguments. It takes the following switches:
-1 One argument per line.
-a Output in ASCII. The default.
-B base Output in given base, 2..32. Unless -u also given, base > 10
shows lowercase.
-b Output in binary.
-C Don't echo anything, just print the number of fields.
-c cmd Run cmd on each argument, replacing $? with the argument itself.
-D Output in decimal.
-d char Field delimiter. Default is end of argument.
-E Print to standard error instead of to standard output.
-e Allow escape sequences
-f file Read from file, then from command line (if any).
-i Read arguments from standard input.
-L len Line width set to len. Default is to ignore line lengths.
-l Turn uppercase to lowercase.
-m Multi-column output.
-N One field per line, numbering each field.
-n Suppress newline.
-O Output in octal.
-o file Write to file instead of standard output.
-q "Quiet mode:" redirect output to /dev/null if not to a file.
-r Print every string that matches each regular expression. Regular
expressions cannot contain + or * modifiers.
-S voice Send to speaker, having the given voice say it. If voice is
a null string, use the default voice.
-s char Separate fields with char, default space.
-t Separate fields with tabs.
-u Convert lowercase to uppercase. With -B, output in uppercase
letters for base > 10.
-V Strip non-printing characters.
-v Make non-printing characters visible.
-w If -l is given, word wrap instead of character wrap. Otherwise,
ignored.
-X Output in uppercase hexadecimal.
-x Output in lowercase hexadecimal.
Test for everyone: write this echo in as little code as possible. C
or rc is permitted. The rules:
- for C: either Standard C (no other libraries) or only libc (no
other Plan 9 libraries)
- for rc: only use programs in the core Plan 9 distribution - no
programs that I have to get myself
- match the behavior EXACTLY as above
- shortest code and fastest run time wins
Winner gets something cool.
What should it do if you mix -f and -i?
The order of interpretation is:
-f
-i
command line
This is lunacy, or profound ignorance. You're duplicating
functionality from about a half dozen other places in here,
perhaps most significantly the shell. The software tools
model gets its profound power from using simple tools
which do one thing well and can be combined in arbitrary
ways. Your... whatever... does lots of arbitrary things,
while not actually doing much of anything for the user.
If this is the "ultimate" echo, I fear for what "something
cool" might be. I don't think my health could take it.
Anthony
Here is my ultimate echo (yours may vary):
NAME
echo -- echo argumens
SYNOPSIS
echo [-n] arguments
DESCRIPTION
echo prints arguments on standard output, followed by newline. If -n
is given, no new line is added.
BUGS
To print -n and a newline, use
echo -n '
'
A bold claim, and a damn silly one.
> 2) That my question and my challenge and my echo were all rhetorical.
If they were rhetorical, you wouldn't have challenged us to implement
your echo in the previous paragraph.
> Here is my ultimate echo (yours may vary):
>
> NAME
> echo -- echo argumens
> SYNOPSIS
> echo [-n] arguments
> DESCRIPTION
> echo prints arguments on standard output, followed by newline. If -n
> is given, no new line is added.
> BUGS
> To print -n and a newline, use
> echo -n '
> '
>
A substandard re-writing of the existing echo(1) man page is your ultimate echo?
Also,
echo -n '
'
doesn't match current behavior and really makes zero sense.
John
--
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
echo -n '-n
'
You missed a few things in this shudderingly horrible
version of echo:
1) no long options, which you need so you can have
the --copyright and --version options.
2) no roman numeral output.
Fortunately, I have no self-respect and some spare time,
so when I implemented this gem of design minimalism I
put those horrible omissions in.
http://www.pell.portland.or.us/~orc/Code/secho/
I would have used the horrible FSF autoconfigure code,
but it turns out that I've got some remaining standards.
-david "share and enjoy!" parsons
secho version xxx.xx
a program to echo its arguments, but improved
use the -h/--help option to get help
distributed under no warranty; use --license for details
Then let's add full locale support and an option to interpret and
print decimal and monetary values, and an option to support formatted
print a la printf and Console.Print (.net - but my memory of that is
fading).