Search code examples
for-loopfishcd

Fish: for loop: Too many args for cd command


If I run a script

#!/usr/bin/fish
cd /home/user/repos/repo1
pwd

works as intended (changes directory and prints that path).

When I place the same logic into a for loop, cd complains about too many arguments even though there are no space and .

#! /usr/bin/fish

set REPOS "/home/user/repos/repo1" "/home/user/repos/repo1"

for REPO_PATH in $REPOS:
    echo $REPO_PATH
    cd $REPO_PATH
    pwd
end

Using relative paths doesn't help,

set REPOS "~/repos/repo1" "~/repos/repo1"

using variables without quotes work outside for loop, same complaint inside for loop.

Works in bash like this

#!/bin/bash
repos=("/home/user/repos/repo1" "/home/user/repos/repo1")
for path in "${repos[@]}"
do
    cd $path
    pwd
done

I've read List and Loops section of fish documentation. I've noticed that cd has a fish-wrapper. Could that be the issue?


Solution

  • Remove the colon.

    The reason this shows the error "Too many arguments" is that calling a variable "...PATH" causes fish to interpret it as a path variable, which means that it will be split on ":" (like $PATH, $LD_LIBRARY_PATH etc).

    So fish goes, sets $REPO_PATH to "/home/user/repos/repo1:", then splits it on the ":", making it a list of "/home/user/repos/repo1" and "".

    That's then passed to cd as two arguments, one being empty, and cd complains about having a second spurious argument.

    So just use

    set REPOS "/home/user/repos/repo1" "/home/user/repos/repo1"
    
    for REPO_PATH in $REPOS
        echo $REPO_PATH
        cd $REPO_PATH
        pwd
    end