6

If I use this link to install docker-compose, I get Not Found error:

[root@hostname ~]# curl -L "https://github.com/docker/compose/releases/download/2.9.0/docker-compose-$(uname -s)-$(uname -m)" -o here
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100     9  100     9    0     0     37      0 --:--:-- --:--:-- --:--:--    37
[root@hostname ~]# cat here
Not Found

That's because the actual file is docker-compose-linux-x86_64 with small l, while:

[root@hostname ~]# echo $(uname -s)-$(uname -m)
Linux-x86_64

It returns capital L.

I saw man curl but did not see any entry for checking case-insensitive link.

2

3 Answers 3

35

It's not curl that decides case-insensitivity at all – link "checking" is the server's decision.

(In other words, HTTP clients do not have the opportunity to see the list of all possible URLs and choose a matching one. The only thing an HTTP client can do is give the exact URL to the server and let the server decide how to respond. Some servers are case-insensitive, some are not.)

But if you already know that you need a lowercase 'linux', you can just transform the uname output before giving it to curl, e.g. by piping it through tr A-Z a-z to change all uppercase letters to lowercase:

docker-$(uname -s | tr A-Z a-z)

or by using Bash's ${var,,} expansion to return a lowercase version of $var:

os=$(uname -s); arch=$(uname -m)

docker-${os,,}-${arch}

Finally, since there's only a small set of accepted values, and because the accepted values aren't guaranteed to be "uname but lowercase" in general, you could indirectly assign each possible value (using if or case blocks), for example:

case $(uname -s) in
    Darwin)    docker_os='darwin';;
    Linux)     docker_os='linux';;
    Cygwin)    docker_os='windows';;
    Microsoft) docker_os='windows';;
    *)         echo "Docker is not supported on this OS!" >&2; exit 1;;
esac

(Note: The 'windows' examples are completely made up. )

5
  • 1
    Technically, case-ness is not a server's decision. It is more like unfortunate implementation reality. As per RFC3986 6.2.2.1 (and references from there taking you further down the rabbit hole) the URI path part is defined to be case-sensitive. HTTPd, for example, conforms with that. IIS does not because whole Windows are case-insensitive... so even simple static file serving would become a huge pain.
    – Fiisch
    Aug 3, 2022 at 6:43
  • 9
    @Fiisch: It's the server's decision because nothing in the spec would forbid servers from serving the same resource at both /FOO and /foo if they wish. The path is only required to be "case-sensitive" from a client's perspective, i.e. so that a weird client (or proxy) wouldn't try to unnecessarily casefold paths before sending them to the server (thus practically requiring servers to become case-insensitive to deal with that), like how some clients already downcase the domain name. Aug 3, 2022 at 7:12
  • 1
    I am not sure about that. The part of RFC3986 (which is for generic URI syntax) reads The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3). And I could not find anything in the HTTP scheme definition which would override that statement.
    – Fiisch
    Aug 3, 2022 at 7:26
  • 6
    It doesn't have to override that statement, because what content the server actually serves at any URL is already outside the scope of the scheme definition. It only means the actual URLs with paths /FOO and /foo must not be considered "the same URL", but they can still have the same content available. Aug 3, 2022 at 7:28
  • 1
    Yes, that is true - and that is a decision of the server; if there was an explicit alias configured in the server config, it would effectively be the same. I was trying to say that - canonically by RFC - URI paths differring only in their case-ness point to (canonically) differrent resources.
    – Fiisch
    Aug 3, 2022 at 8:49
17

Case sensitivity for the part after the domain names is up to the server.

To fully emulate case-insensitivity of the server, curl would have to try up to all possible combinations (…LiNUx…, …linUX…) and there's an enormous number of them.

If you know the server uses all-lowercase strings then a reasonable thing to do is to convert the URL to lowercase before supplying to curl. Example for Bash:

url="https://github.com/docker/compose/releases/download/2.9.0/docker-compose-$(uname -s)-$(uname -m)"
url="${url,,}"
curl -L "$url" -o here

BUT the right URL is with v2.9.0 and the server in question is actually case-insensitive for the docker-compose-… component. The simplest fix for you is just to add the missing v:

curl -L "https://github.com/docker/compose/releases/download/v2.9.0/docker-compose-$(uname -s)-$(uname -m)" -o here
#                                           this was missing ^

Without this v no conversion can help.

3
  • 4
    XY problem, amirite?
    – mtak
    Aug 2, 2022 at 7:36
  • 10
    url="${url,,}" Ah, the well-known clarity of the self-explanatory code in unix shells...
    – GACy20
    Aug 2, 2022 at 15:10
  • @GACy20, see $url:al in tcsh or $url:l or ${(L)url} in zsh as slightly more legible ones. Unix shells tend to go for brevity over legibility as they're primary intended for interactive use. If you don't like brevity, in fish, a full equivalent of zsh's $url:l may look like set url (string lower -- $url | head --bytes=-1 | string collect --no-trim-newlines) (which can simplified when $url like here doesn't contain newline characters).
    – sch
    Aug 5, 2022 at 13:43
6

As others already pointed out, case insensitivity is configured serverside, there is nothing you can do to change that from your machine.

You could however use some other tools to convert the string to lowercase:

╭─user@machine ~ ‹main› 
╰─$ echo $(uname -s)-$(uname -m) | tr '[:upper:]' '[:lower:]'                                                                                                                                             
linux-x86_64

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .