shellfishsubcommand

execute a subcommand in a different directory as the current one in fish?


I want to move a file from a directory different from the current directory. This is the solution I thought of:

mv (cd ~/Downloads; ls -t | head -1 | xargs -I {} readlink -f {}) ./

There is probably a better way, but along the way I found that my expectation of the change of directory staying inside the subcommand was wrong: Running cd changes the directory where mv is being executed.

So, is there a way to change directories only for the current subcommand, without affecting the top command?


Solution

  • Right, many of us coming from Posix shells like bash or zsh are used to being able to run a command substitution like this using $() or just backticks and leave the parent shell environment untouched. It's a nice trick, IMHO.

    On the other hand, fish doesn't automatically create a subshell when using its command substitution operator (). There's a feature request here for that, but the workaround (as suggested there) is fairly straightforward -- Just explicitly create a subshell inside the command substitution. E.g.:

    mv (fish -c 'cd ~/Downloads; ls -t | head -1 | xargs -I {} readlink -f {}') ./
    

    The downside is that syntax highlighting/checking doesn't work in the quoted text, and quoting/escaping rules get more complicated.