skip to Main Content

I see Define an alias in fish shell, and I know how to setup alias and/or functions,

But is it possible to setup different alias target based on OS? Maybe use function?

What I experience isn’t standard I believe. I am currently using one FISH setup (dotfile) for all of my systems, such as macOS and Linux (Arch or Debian). I noticed that sometime for some program, it’s not same across different OS.

For example, I try to use bat to replace cat and on Archlinux, bat is a program that you can install from pacman, but on Debian, if you install bat with apt install bat, you will get batcat instead.

My current alias setup is

alias cat='bat' 

but with this setup, Debian will throw error.

What I plan to do is something that can use different program based on different operation system. Or if possible, use first available command if it’s available. Something like

function cat 
  if os == 'debian': use batcat
  elseif os == 'archlinux': use bat
end

Or something probably better

function cat
  try to use bat first, if does not exist, try to use batcat, if not fallback to cat
end

I believe on ZSH, we can do alias cat="bat | cat" for OR operation. But seems like it’s not available on FISH

What is the best option for it?

2

Answers


  1. EDIT: Just realized the fatal flaw in this… it can’t accept arguments

    EDIT 2: Switched to exporting the variables to hopefully allow arguments. Check out the Github link below for maybe some other ideas?

    After a little bit of digging around I came up with this:

    #!/bin/fish
    
    
    function func -a commandvar -a argvar
        switch (uname)
        case ArchLinux
            command "$$commandvar[0]" "$$argvar[0]"
        case Debian
            command "$$commandvar[1]" "$$argvar[1]"
        case MacOS
            command "$$commandvar[2]" "$$argvar[2]"
        case '*'
            echo Hi, stranger!
        end
    end
    
    # you execute the command with this
    set -x commands bat batcat idk_mac
    set -x args my_arg1 my_arg2
    func commands args
    
    # you could also wrap the above 3 commands in another function like 
    your 'cat' function if you know the number of arguments.
    

    I have not tested this so you will have to play around with it.

    Here are some links that I found that gave me some ideas:
    https://fishshell.com/docs/current/language.html#the-switch-statement

    https://github.com/fish-shell/fish-shell/issues/6150#issuecomment-536593949

    Login or Signup to reply.
  2. You can definitely do this with a function that chooses the first available command.

    function cat
        if type -q bat
            command bat $argv
        else
            command cat $argv
        end
    end
    

    Doing OS detection is a little more involved (and unreliable), and I won’t go into the specifics – there are lots of other StackOverflow answers on how to detect the operating system. However, you could start with something like this:

    function cat
        if test -f /etc/arch-release # Arch Linux
            command bat $argv
        else if test -f "/etc/debian_version" # Debian
            command cat $argv
        else # maybe this is macOS or solaris?
            command supercat $argv
        end
    end
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search