LWN.net Logo

Fish - The friendly interactive shell

Fish - The friendly interactive shell

Posted May 20, 2005 15:25 UTC (Fri) by liljencrantz (guest, #28458)
In reply to: Fish - The friendly interactive shell by diehl
Parent article: Fish - The friendly interactive shell

Hi. Glad you like fish.

1) Actually the exact opposite is happening. If the parameter '*.txt' does not match any files, it is expanded to exactly 0 parameters. In other words, you end up running ls with _no_ parameters, in which case ls will list the contents of the current directory.

2) I think you are referring to another .desktop file. The name overloading in Linux is pretty confusing. The .desktop files I'm referring to is a file hierarchy usually located somewhere under /usr/share.

Try using the mimedb command. If the command 'mimedb foo.txt' returns 'text/plain', the mime database is installed correctly. If 'mimedb -i text/plain -a' returns something like 'gedit %U', the mimedb command can find the .desktop files. Both of these are needed for the open command to work.


(Log in to post comments)

Fish - The friendly interactive shell

Posted May 20, 2005 16:06 UTC (Fri) by diehl (guest, #6413) [Link]

1) Ok, I understand why "ls *.txt" lists all files when no txt files exists. However
this not behavior I particularly want. tcsh and bash do not do this. Is there any
way to get "ls *.txt" to return nothing or "No such file or directory" which is what
it returns if "ls" a specific file which does not exist.

2) As far as mimedb goes "mimedb -i text/plain -a" returns nothing. I poked
around found a bunch of *.desktop files in various subdirectories
under /usr/share. So it would seem that I have to somehow tell mimedb to
look in these subdirectories. Can this be done with symbolic links or
environmental variables?

It might be nice to have the open return some type of error message if it does
not know what to do with the file to clue the user into the problem.

Fish - The friendly interactive shell

Posted May 20, 2005 23:51 UTC (Fri) by kingdon (subscriber, #4526) [Link]

As for the wildcard issue, a lot of utilities will read from standard in if called with no arguments. So having a non-matching wildcard expand to no arguments doesn't seem so good.

There are two traditional behaviors: pass along "*.txt" to the program (most/all Bourne-derived shells), or give an error and don't even call the program (csh). The latter makes more sense to me (one can always quote the *.txt if that's what one means).

Fish - The friendly interactive shell

Posted May 21, 2005 1:06 UTC (Sat) by liljencrantz (guest, #28458) [Link]

1) I don't like the bash way of doing this, since it is inconsistent and for me at least it is very rarely what I want. As another poster said, csh refuses to execute commands with wildcards that match nothing. This seems better at least, but from a language viewpoint, neither is very logical. But I'll consider changing the way fish handles this.

2) I will look into how the mimedb command searches for the .desktop hierarchy. It has been a few months since I touched that code, so my memory is a bit hazy. I'll get back to you.

Fish - The friendly interactive shell

Posted May 26, 2005 15:25 UTC (Thu) by mikachu (guest, #5333) [Link]

In zsh, you can select between two behaviours, either you get an error when * doesn't match anything, or it expands to nothing as in fish. (and when in the first mode, you can write *(N) to make it expand to nothing if it doesn't match). In bash i think * is left as a literal * if it doesn't match, so the file not found message is actually from ls, not the shell. Not 100% sure about that one though.

Fish - The friendly interactive shell

Posted May 26, 2005 15:51 UTC (Thu) by diehl (guest, #6413) [Link]

Well, in my opinion I perfer to have ls have the behavior of of saying "no file
found" if a file does not exist, rather than giving an entire directory listing if the
file does not exist, which I find confusing. So I vote for implementing that
behavior, at least as an option.

Fish - The friendly interactive shell

Posted May 27, 2005 12:07 UTC (Fri) by liljencrantz (guest, #28458) [Link]

The reason fish does what it does right now is that I regularly do things like:

for i in *.c; [...]; end

Inside of shellscripts. I expect this to work even when *.c does not match anything. If *.c is not expanded in this case, this will result in stupid behaviour, unless I add an explicit check, which is clearly dumb.

Maybe the perfect compromise is to have *.c expand to nothing inside of scripts, but emit a syntax error in interactive mode?

Fish - The friendly interactive shell

Posted May 30, 2005 17:10 UTC (Mon) by Jyhem (guest, #29388) [Link]

Are you saying that if you write

for i in *.bak; rm $i; end

then if there is no backup file present, I will have all the files in the directory deleted ?

I hope you intend to implement "undo" :-D

Fish - The friendly interactive shell

Posted May 30, 2005 21:15 UTC (Mon) by liljencrantz (guest, #28458) [Link]

Look at your example again... If *.bak does not match anything, the for loop body will execute exactly zero times. So the rm command will _never_ be run. And even if it had, running rm without any parameters doas not remove anything. So you are doubly safe.

Fish - The friendly interactive shell

Posted Jun 1, 2005 19:29 UTC (Wed) by kjetilho (guest, #30261) [Link]

It would be bad to make the behaviour in scripts different from that in interactive use, often I just paste my recent command history and make it a script for later use. The obviously correct ;-) solution is to make globbing work differently in list context, ie. when used as an iterator in for loops.

Doing this correctly in bash is quite painful -- you need to handle case where the glob matches literally:

  for i in *.c; do
    [ "$i" = "*.c" -a ! -e "$i" ] && break
    do_stuff "$i"
  done

fish sure is neater:

  for i in *.c; do_stuff $i; end

Fish - The friendly interactive shell

Posted Jun 9, 2005 12:11 UTC (Thu) by liljencrantz (guest, #28458) [Link]

So many solutions to a single problem. What is really needed is a 'Do what i mean' command...

Fish - The friendly interactive shell

Posted May 27, 2005 14:02 UTC (Fri) by liljencrantz (guest, #28458) [Link]

This is very typical for zsh. Whenever there is a difficult design tradeof, zsh implements multiple solutions and lets the user choose. This may sound like a good way of doing things, but I think it is a cop out and a bad idea. Here is why:

Multiple implementations means that more time has to be spent on maintaining the code, it becomes more difficult to add new features and the number of possible configuration combinations means that it becomes impossible to test all configuration combinations, which leads to an increase in rare, hard to nail down bugs. And if you eventually figure out the _right_ way of doing something, it is difficult to change the code, because that means removing configuration options.

Fish - The friendly interactive shell

Posted Aug 21, 2008 21:24 UTC (Thu) by samroberts (subscriber, #46749) [Link]

About your re-implementation of NeXT's "open" using mimecap and custome 
files:

see does exactly this, it's part of the mime handling utilities.


Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds