Error: fish: ${ is not a valid variable in fish

49 Views Asked by At

So I'm trying to run this command to turn files into a .chd file:

for i in *.cue; do chdman createcd -i "$i" -o "${i%.*}.chd"; done

But I get this error:

fish: ${ is not a valid variable in fish.
for i in *.cue; do chdman createcd -i "$i" -o "${i%.*}.chd"; done

Which is boggling to me cuz I run this command to convert flac to ogg and it works just fine:

find . -name "*flac" -exec sh -c 'oggenc -q 7 "$1" -o ~/vorbis/"${1%.*}".ogg' _ {} \;

The second line uses ${ and works fine. So why is the first command giving me that error for ${? I've searched around and can't find much on the subject. I'd really like to understand so if I use a similar string in the future I'll know what to do. I don't really know much about coding, so this really has my interest. And frustration at the same time.

What I have tried is replacing ${ with $(, and other variants. But nothing has worked. The command works fine in zsh, so it's something with Fish.

I did find this

Looks like someone having a similar problem, but... do I really have to install something (ghc) to get this working? Seems like there would be a different work around.

2

There are 2 best solutions below

2
larsks On

Your second working command is running commands in a Bourne shell (/bin/sh); that's what the -exec sh -c '...' is for in your find command.

On the other hand, you're trying to run the first command directly in the fish shell. That's not going to work. You could explicitly run it using /bin/sh, just like in your find command:

sh -c 'for i in *.cue; do chdman createcd -i "$i" -o "${i%.*}.chd"; done'
0
Shawn On

The proper fish version of that loop is:

for i in *.cue; chdman createcd -i $i -o (path change-extension chd $i); end

fish is not a Bourne-style shell like sh or bash or zsh and does not have the same syntax. Trying to treat it like it is in that family is of course not going work very well. You should read through its documentation if you're planning on using it for scripting. I'd start with fish for bash users.