1

I am on a Windows 11 machine (Powershell v5.1) and I am trying to alias the rust rewrite of coreutils to appropriate commands in powershell. For example, I need to call coreutils echo to access the echo command and similarly for mv, cat, cp etc. So I wrote a function to output the command string, and I am passing it to the Set-Alias cmdlet.

However I am getting the following error.

echo : The term 'coreutils echo' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ echo
+ ~~~~
    + CategoryInfo          : ObjectNotFound: (coreutils echo:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Here is my powershell config.


# neovim config alias
function Open-NeovimConfig {
  $CurrPath = pwd
  cd C:\Users\adity\AppData\Local\nvim\lua\user\
  nvim .\init.lua
  cd $CurrPath
  }

# coreutils command specifier
function Coreutils-Cmd($Cmd) {
    return "coreutils $Cmd"
}

Set-Alias nvimc Open-NeovimConfig
Set-Alias ls lsd -Option AllScope
Set-Alias echo (Coreutils-Cmd "echo") -Option AllScope
Set-Alias cat (Coreutils-Cmd "cat") -Option AllScope
Set-Alias cp (Coreutils-Cmd "cp") -Option AllScope

EDIT: Based on Santiago's comment, I did the following. However, there is a lot of repeated logic. Any suggestions to improve?

function echo {coreutils echo $args}
function cat {coreutils cat $args}
function rm {coreutils rm $args}
function cp {coreutils cp $args}
function mv {coreutils mv $args}
Aditya Wagh
  • 182
  • 1
  • 2
  • 14
  • Thanks! I got it to work but I needed to write a lot of functions. Any suggestions to improve this? Added more info in the post. – Aditya Wagh Feb 25 '23 at 05:11

1 Answers1

2

You could automate the process using a loop and Set-Item to dynamically define those functions:

foreach($cmd in 'echo', 'cat', 'rm', 'cp', 'mv') {
    Remove-Alias $cmd -ErrorAction SilentlyContinue
    Set-Item function:$cmd -Value { coreutils $cmd $args }.GetNewClosure()
}

This only works because the name of the function happens to also be the same as the argument passed to coreutils. Also, the use of .GetNewClosure() is needed here, otherwise the scriptblocks would use the last value of $cmd.

Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • Thanks! This is very helpful. How should I modify this if I want this to happen for every command in `coreutils`? – Aditya Wagh Feb 25 '23 at 05:50
  • 1
    @AdityaWagh I don't know the commands in `coreutils` but if you have a full list of them then you can change the collection in the loop and it would work – Santiago Squarzon Feb 25 '23 at 05:53
  • 2
    @AdityaWagh If you put all 119 command names into the loop header it won't be very readable. ;-) You could put them into a here-string and use `-split` to create an array: https://gist.github.com/zett42/72fe42c418d53ad03d5e17ffd7fd8104 – zett42 Feb 25 '23 at 08:40
  • 2
    @SantiagoSquarzon: Cool. Reminds me of how all the drive-letter-named functions have the identical defintion: `{ Set-Location $MyInvocation.MyCommand.Name }`. – Keith Miller Feb 25 '23 at 12:29