okdana
The latter is more serious imo, because those attributes live on your file system basically for ever, and they're preserved when transferring to another compatible file system or even when archived in a zip file. The meta-data can ride along with the files to completely unrelated systems even years after the fact. So if you AirDrop some files to your computer and then zip them up, anyone you send that zip to (a journalist, a public file-hosting site, w/e) will have your full legal name to go with them.
Even sharing your name through the interface seems questionable -- the fact that you and another person have each other's phone numbers is not necessarily an indication that you want to share your real names with each other. (Though i guess someone could usually find it out anyway if they already had your phone number.)
I reported this to Apple, but i don't think they care. Seems like it's by design.
But, even with relatively simple commands, that type of completion is very limited compared to the contextual functionality that proper zsh completion functions provide. These functions know...
* Which arguments are meaningful to complete more than once — there's no reason to complete `-a` again after you've already entered `ls -a`, but an option like `-v` might be cumulative
* Which arguments are meaningful to complete in the presence of other arguments — there's no reason to complete `-A` if you've already entered `ls -a`, since those two options are exclusive
* Whether the command supports permutation — GNU tools usually do (`ls mydir/ -al`), BSD ones usually don't (`ls -al mydir/`)
* Whether options can be stacked — some commands require `-a -b -c` instead of `-abc`
* How options can be joined to their optargs — GNU supports both `--foo bar` and `--foo=bar`, curl supports only `--foo bar`, grep supports both `-m 3` and `-m3`, tree supports only `-L 3`
* How the current argument might be affected by a previous one — if you've entered `make -C mydir` it's useful to complete targets from mydir/Makefile
* How to complete multi-part arguments — if you press tab after `ssh foo@` you probably want to complete a host name or IP
* The descriptions of arguments — zsh can explain what the difference between `always` and `auto` is, and even when an argument is arbitrary, it can explain what format it takes, what the default is, what the min/max are, &c.
* Probably most importantly, the values of optargs and operands — just blindly offering file names or presenting a metavar parsed from --help (like WHEN or TYPE) is not very nice; a useful completion function will offer package names, man-page names, compression levels, PIDs, NIC addresses, or whatever else is appropriate
I know it's technically possible to do some of this with bash completion functions, but most don't, probably because the infrastructure isn't there. fish is nicer, but even it doesn't (can't?) usually go that far with it.
This level of richness (along with related UI stuff like menu selection) is why a lot of people switch to zsh even if they don't really care about its scripting features and modules and stuff. It's probably why i started using it originally.
A way to specify completion behaviour declaratively would be really cool, but if it's just going to be dumbed down to bash-like functionality, i'm not sure it's going to gain much more traction with zsh users than _gnu_generic and bashcompinit (zsh's bash-completion compatibility shim) have.
I can't think of how macOS could have previously supported NUL bytes in file names without those files existing in a separate universe that can only be interacted with by software that uses some proprietary Apple API. And if that's really how it worked, i feel like that was the real mistake all along...?
But if you did want to run them with zsh, most simple scripts that just set environment variables, string together commands, or redirect to files should work without any changes. The most obvious difference for basic scripts like that is that zsh doesn't split parameter-expansions on white space by default (so if you did something like `opts='-a -b -c'; mycmd $opts` it wouldn't work without additional, minor, modifications)
But i do think the misunderstanding i mentioned is very common, as illustrated by the fact that the GP seems to think that OMZ itself provides zsh's completion functionality. It's also a frequent point of confusion with people seeking assistance on zsh's IRC channel.
The down side is that it's functionally very limited compared to zsh. fish's completion functions are easy to maintain, but the trade-off is that they don't offer the fine-grained contextual control over behaviour that zsh's do. Features like globbing, sub-shells, job control, co-processes, modules, &c., are absent or extremely limited. There are fewer knobs and switches, though as mentioned it tries to do the right thing for most people by default. And a consequence of the syntax being clearer is that it's also much more verbose, which i guess you may or may not appreciate.
Over-all i think fish is a good shell for the (very common) type of person who doesn't really care about shells but was drawn to zsh just because it has nicer completion than bash and lets you write fancy prompts. I don't think it's a good fit, yet, for people who write complex scripts or regularly make use of stuff like extended globs, background jobs, and fancy parameter expansions.
(In zsh's case, i think that's partly the project's own fault; it has very underwhelming defaults and a very overwhelming set-up process for new users.)
All of PHP's process-execution methods (except one, which is unusable on many systems) go through the shell, so by virtue of that it also searches the PATH.
To be clear, the shell isn't really 'interpreting' anything here — it knows absolutely nothing about the argument conventions of whatever program you're running[0]. All it's doing is passing a list of arguments to an executable; how the executable deals with that is up to it.
And this isn't only a shell problem — it's an issue when you pass arbitrary arguments to ANY external utility in ANY language. For example, maybe you have some kind of tool that calls grep:
# Perl
exec '/usr/bin/grep', '-R', $input, 'mydir';
# PHP (with Symfony Process)
(new Process(['/usr/bin/grep', '-R', $input, 'mydir']))->run();
# Python
subprocess.run(['/usr/bin/grep', '-R', input, 'mydir'])
# C
execv("/usr/bin/grep", (char *[]) {"grep", "-R", input, "mydir", NULL});
All of these are safe in the sense that there's no risk of shell command injection (in fact, only the PHP one even calls the shell), but NONE of them are safe against this problem, where the input value might begin with a hyphen. In this grep scenario it's probably not a security issue, but it can produce confusing results for the user if nothing else.As others mentioned, you must ALWAYS use '--' to mark the end of option processing when you do something like this.
[0] Technically the shell knows about the conventions of its built-ins, but even those mostly handle arguments in a similar fashion to external utilities, where an arbitrary argv is fed to a function and then parsed using some getopts-like method.
% sudo ip link set eth3 down
% sudo ip link set eth3 name "'deal-with-it'"
% sudo ip link show "'deal-with-it'"
5: 'deal-with-it': <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 10000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
The only interface-name restrictions iproute2 sets is that they can't contain NUL, slash, or white space, and they can't be longer than 15 characters.The fact that the capitalist class doesn't appreciate tactics that complicate or reduce the effectiveness of their preferred business practices doesn't mean that those tactics represent an attack on capitalism itself. Corporations violently oppose taxes and regulations, too, but neither threatens capitalism or its fundamental class structure.
>Unions started as an instrument of class struggle and remain precisely that, the fact that that is even slightly controversial is more representative of the ideological climate of today and specifically this website.
It's hardly peculiar to the 'climate of today'. Karl Marx, 1865:
At the same time, and quite apart from the general servitude involved in the wages system, the working class ought not to exaggerate to themselves the ultimate working of these everyday struggles. They ought not to forget that they are fighting with effects, but not with the causes of those effects; that they are retarding the downward movement, but not changing its direction; that they are applying palliatives, not curing the malady. They ought, therefore, not to be exclusively absorbed in these unavoidable guerilla fights incessantly springing up from the never ceasing encroachments of capital or changes of the market. They ought to understand that, with all the miseries it imposes upon them, the present system simultaneously engenders the material conditions and the social forms necessary for an economical reconstruction of society. Instead of the conservative motto: “A fair day's wage for a fair day's work!” they ought to inscribe on their banner the revolutionary watchword: “Abolition of the wages system!”
And in regards to unions specifically:
Trades Unions work well as centers of resistance against the encroachments of capital. They fail partially from an injudicious use of their power. They fail generally from limiting themselves to a guerilla war against the effects of the existing system, instead of simultaneously trying to change it, instead of using their organized forces as a lever for the final emancipation of the working class that is to say the ultimate abolition of the wages system.
zsh and fish don't really belong in the same comparison IMO.
zsh is, like bash, a ksh-like shell with a Bourne-style grammar. Obviously it depends on the exact use case, but in practice, for basic scripting purposes, it is almost a super-set of bash, and it provides several emulation options (like sh_word_split) specifically designed to increase compatibility with POSIX and with bash in particular. It even provides shims to support bash completion functions. (It is fair to point out that, even with all the emulation stuff enabled, it's still not completely bash-compatible, nor POSIX-compliant. It's close enough that the changes required are usually extremely trivial, though.)
fish on the other hand has its own completely different grammar and makes no attempt to provide POSIX/ksh/bash compatibility at all.
(I don't think there's any such plan for the various BSD greps, so if you use those exclusively you're probably fine.)
grep '^|.*PLUGH.*'zsh also performs much better in practice than bash. Not only does it run the same code faster, it subsumes a great deal of functionality that normally requires external utility calls (which are very slow) into the shell itself.
For example:
* zsh has native floating-point arithmetic, so no need for `awk` or whatever. It can even format (digit-group) the numbers
* Regular-expression matching with =~ can be replaced by extended globs (which offer similar functionality but are significantly faster in most cases)
* `basename`, `dirname`, `readlink -m`, and `readlink -f` can be replaced by parameter-expansion modifiers
* `sort` can be replaced by parameter-expansion flags
* `grep` can be replaced by parameter-expansion flags and extended globs
* `find` (including its `-type` and `-exec` features) can be replaced by globs
* `date` can be replaced by prompt expansion or the `zsh/datetime` module
* `cp`, `mkdir`, `rm`, and so on can be replaced by the `zsh/files` module
* `stat` can be replaced by the `zsh/stat` module
* `column` can be replaced by `print -c` or `print -C`
> there are massive swaths of the program, entire subsystems, that are more or less completely undocumented
Like what? I'm not sure i'd noticed that myself. Sometimes the documentation is vague, maybe hard to find (e.g., the completion system's documentation is a bit overwhelming), but it's always been there when i went looking for it.
> Also, the ad-hoc "plugin" ecosystem is in a strange and fragmented state.
The plug-in ecosystem (i assume you mean OMZ, zplug, and stuff like that) is entirely unofficial and most of the zsh developers don't seem to care for any of it because it tends to be slow, error-prone, and often just unnecessary. It's also a major support burden for the people on IRC and in the mailing list, which doesn't endear them to it. Might be cool to have something official though.
> It's a shame that more people don't write actual modules in C (yes, Zsh has a native module system), but then again, is the API even documented?
I don't think it is, there's just an example module you can build. bash also supports loadable modules and it's the same way AFAIK.
> One more thing about Zsh: it has emacs syndrome. Do your really need an FTP client and calendar built into your shell?
Most of the weird stuff like the FTP client and calendar and Tetris game are optional modules or even just regular shell scripts. None of them are enabled by default and packagers can omit them (and they often do, especially with static builds).
: <<- 'NOOP'
some
code
here
NOOP
In some languages there is a very slight performance impact to doing this, however. Especially in the shell, because it actually has to juggle file descriptors whenever a heredoc or herestring is involved — even if you're directing it into a built-in like `:`. (It only costs a few-dozen microseconds though.)Also, heredocs are irritating because they usually can't deal with indentation properly. bash and zsh support the `<<-` operator which allows you to indent the closing delimiter, but only if you use tabs. Most other languages require the delimiter to be the first thing on the line, which is tedious and confusing.
Python's triple-quotes seem to solve all of these problems, and they're one of the best things about Python's grammar IMO. I wish every language had that, combined with the ability to treat expressions as statements. It'd be a little ugly in C-like languages, but certainly usable:
'''
my comment
''';I think i'm a version or two behind the latest, so maybe it's better now, but that's been my experience so far.
Anyway, in spite of the above i still prefer it to ObjC.
If your blue doesn't look right on your dark background, why are you using that blue?
If your yellow doesn't look right on your light background, why are you using that yellow?
I mean i get how this can be a problem with hard-coded arbitrary values — you can't ever guarantee that e.g. #ff6600 will go with anyone's particular colour scheme. But these 8 or 16 standard colours are not hard-coded, they're configurable in every terminal i've ever used, including Windows's shitty command prompt. They can and should be set to a value that's appropriate for your background and text colours.
Maybe this is more a fault of the terminal/theme developers for providing unusable defaults. idk.
I suppose the two main benefits are
(a) neither the writer nor the reader has to remember which punctuation characters are meta-characters (you just have to remember that it's always a literal if it's escaped), and
(b) in implementations like PHP's which try to replicate the Perl-style 'delimited' syntax (e.g., /foo/), it prevents characters in the pattern from conflicting with the delimiters.
Maybe there's some other advantage but i can't think of what.