0

I am trying to compare version in windows terminal. It works great in Git Bash but in Windows terminal it shows gibberish and wrong result?

verlte() {
    [  "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
}

verlt() {
    [ "$1" = "$2" ] && return 1 || verlte $1 $2
}

verlte 2.5.7 2.5.6 && echo "yes" || echo "no" # no
verlt 2.4.10 2.4.9 && echo "yes" || echo "no" # no
verlt 2.4.8 2.4.10 && echo "yes" || echo "no" # yes
verlte 2.5.6 2.5.6 && echo "yes" || echo "no" # yes
verlt 2.5.6 2.5.6 && echo "yes" || echo "no" # no

Result in Windows terminal

Windows terminal result

Result in Git Bash

Bash result

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • `[` is a POSIX command but it's part of the `[]` operator in powershell – phuclv Apr 21 '22 at 06:45
  • @phuclv thanks, can the script changed make it work on windows? I have tried but didn't work. – i_am_learning Apr 21 '22 at 07:06
  • 1
    of course you can, but you need to use the shell's syntax. Bash, ksh, csh, zsh, cmd, powershell... all have different syntaxes and you can't use bash syntax on another shell – phuclv Apr 21 '22 at 09:34

2 Answers2

1

Borrowing from Sort a list that contains version numbers properly, which references How to sort by file name the same way Windows Explorer does?, here's my attempt at converting to PowerShell syntax:

# compare two arbitrary version strings using natural sorting
# allows strings to contain non-numeric components
function verlte {
    param(
        [string]$v1,
        [string]$v2
    )

    function ToNatural {
        param( [string]$v )
        [regex]::Replace($v, '\d+', { $args[0].Value.PadLeft(20) })
    }
    
    (ToNatural $v1) -le (ToNatural $v2)
}

function verlt {
    param(
        [string]$v1,
        [string]$v2
    )

    if ($v1 -eq $v2) { return $false }
    verlte $v1 $v2
}

verlte 2.5.7 2.5.6 # False
verlt 2.4.10 2.4.9 # False
verlt 2.4.8 2.4.10 # True
verlte 2.5.6 2.5.6 # True
verlt 2.5.6 2.5.6 # False
  • for comparing file names you need to use natural sort but specifically for versions you don't actually need that – phuclv Apr 22 '22 at 01:27
  • My goal was to replicate the behavior of GNU `sort -V`, which uses a [natural sort](https://www.gnu.org/software/coreutils/manual/html_node/Version-sort-and-natural-sort.html), i.e. allowing arbitrary non-numeric text in the input string. I wanted to replicate the behavior in the code provided provided by [i_am_learning](https://stackoverflow.com/users/17533344/i-am-learning) – Slartiprefect Apr 22 '22 at 13:05
1

It seems you're comparing versions. In PowerShell and .NET framework there are already [version] to do that:

PS C:\Users> [version]"2.5.7" -le [version]"2.5.6"
False
PS C:\Users> [version]"2.4.10" -lt [version]"2.4.9"
False
PS C:\Users> [version]::new(2, 4, 8) -lt [version]::new(2, 4, 10)
True
PS C:\Users> [version]"2.5.6" -le [version]"2.5.6"
True
PS C:\Users> [version]::new(2, 5, 6) -lt [version]::new(2, 5, 6)
False

See PowerShell Comparison Operators for more information


Note that Windows Terminal is a terminal and can't run anything. Same to other terminals like conhost (the default terminal on older Windows), term, xterm, iterm, konsole... The thing that runs commands is called the shell and a shell must be connected to some terminal to work. So saying "running in Windows Terminal" makes almost no sense because the error comes from the shell. Your command is a bash command so obviously if you run bash in Windows Terminal then it'll run properly. It's unclear which shell you're using but

  • In PowerShell [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ] completely fails to parse because in PowerShell ` is an escape character (which means your command doesn't terminate), and =, [/] in PowerShell are an operator instead of a normal character like in bash
  • In cmd $ isn't the character for variable and argument substitution, and ` also has no special meaning, so if there's a [.exe in your path then cmd will pass the whole literal command to the [ command which will fail to compare anything

Each shell has its own syntax, don't try to run commands written for a shell on another completely different one

phuclv
  • 37,963
  • 15
  • 156
  • 475