Open File (open)

Open a file with a preferred handler

Description

open is a smart tool for reading files:

  1. It will read a file from disk or a HTTP(S) endpoints
  2. Detect the file type via file extension or HTTP header Content-Type
  3. It intelligently writes to stdout
  1. If there are no open handlers then it will fallback to the systems default. eg open (on macOS, Linux), open-xdg (X11), etc.

Usage

open filename[.gz]|uri -> <stdout>

Examples

» open https://api.github.com/repos/lmorg/murex/issues -> foreach issue { out "$issue[number]: $issue[title]" }

Detail

File Extensions

Supported file extensions are listed in config under the app and key names of shell, extensions.

Unsupported file extensions are defaulted to generic, *.

Files with a .gz extension are assumed to be gzipped and thus are are automatically expanded.

MIME Types

The Content-Type HTTP header is compared against a list of MIME types, which are stored in config under the app and key names of shell, mime-types.

There is a little bit of additional logic to determine the Murex data-type to use should the MIME type not appear in config, as seen in the following code:

package lang

import (
    "regexp"
    "strings"

    "github.com/lmorg/murex/lang/types"
)

var rxMimePrefix = regexp.MustCompile(`^([-0-9a-zA-Z]+)/.*$`)

// MimeToMurex gets the murex data type for a corresponding MIME
func MimeToMurex(mimeType string) string {
    mime := strings.Split(mimeType, ";")[0]
    mime = strings.TrimSpace(mime)
    mime = strings.ToLower(mime)

    // Find a direct match. This is only used to pick up edge cases, eg text files used as images.
    dt := mimes[mime]
    if dt != "" {
        return dt
    }

    // No direct match found. Fall back to prefix.
    prefix := rxMimePrefix.FindStringSubmatch(mime)
    if len(prefix) != 2 {
        return types.Generic
    }

    switch prefix[1] {
    case "text", "i-world", "message":
        return types.String

    case "audio", "music", "video", "image", "model":
        return types.Binary

    case "application":
        if strings.HasSuffix(mime, "+json") {
            return types.Json
        }
        return types.Generic

    default:
        // Mime type not recognized so lets just make it a generic.
        return types.Generic
    }
}

// MurexToMime returns the default MIME for a given Murex data type.
// The intended use case for this is for GET and POST requests where the body
// is STDIN.
func MurexToMime(dataType string) string {
    return defaultMimes[dataType]
}

HTTP User Agent

open’s user agent is the same as get and post and is configurable via config under they app http

» config -> [http]
{
    "cookies": {
        "Data-Type": "json",
        "Default": {
            "example.com": {
                "name": "value"
            },
            "www.example.com": {
                "name": "value"
            }
        },
        "Description": "Defined cookies to send, ordered by domain.",
        "Dynamic": false,
        "Global": false,
        "Value": {
            "example.com": {
                "name": "value"
            },
            "www.example.com": {
                "name": "value"
            }
        }
    },
    "default-https": {
        "Data-Type": "bool",
        "Default": false,
        "Description": "If true then when no protocol is specified (`http://` nor `https://`) then default to `https://`.",
        "Dynamic": false,
        "Global": false,
        "Value": false
    },
    "headers": {
        "Data-Type": "json",
        "Default": {
            "example.com": {
                "name": "value"
            },
            "www.example.com": {
                "name": "value"
            }
        },
        "Description": "Defined HTTP request headers to send, ordered by domain.",
        "Dynamic": false,
        "Global": false,
        "Value": {
            "example.com": {
                "name": "value"
            },
            "www.example.com": {
                "name": "value"
            }
        }
    },
    "insecure": {
        "Data-Type": "bool",
        "Default": false,
        "Description": "Ignore certificate errors.",
        "Dynamic": false,
        "Global": false,
        "Value": false
    },
    "redirect": {
        "Data-Type": "bool",
        "Default": true,
        "Description": "Automatically follow redirects.",
        "Dynamic": false,
        "Global": false,
        "Value": true
    },
    "timeout": {
        "Data-Type": "int",
        "Default": 10,
        "Description": "Timeout in seconds for `get` and `getfile`.",
        "Dynamic": false,
        "Global": false,
        "Value": 10
    },
    "user-agent": {
        "Data-Type": "str",
        "Default": "murex/1.7.0000 BETA",
        "Description": "User agent string for `get` and `getfile`.",
        "Dynamic": false,
        "Global": false,
        "Value": "murex/1.7.0000 BETA"
    }
}

Open Flags

If the open builtin falls back to using the systems default (like open-xdg) then the only thing that gets passed is the path being opened. If the path is stdin then a temporary file will be created. If you want to pass command line flags to open-xdg (for example), then you need to call that command directly. In the case of macOS and some Linux systems, that might look like:

exec open --flags filename

Synonyms

See Also


This document was generated from builtins/core/open/open_doc.yaml.

This site's content is rebuilt automatically from murex's source code after each merge to the master branch. Downloadable murex binaries are also built with the website.

Last built on Wed Sep 18 21:18:57 UTC 2024 against commit c037883c03788357164e9846c84d9f777251495d9452a8e.

Current version is 6.3.4225 (develop) which has been verified against tests cases.