openOpen a file with a preferred handler
open is a smart tool for reading files:
Content-Typeopen (on macOS, Linux), open-xdg
(X11), etc.open filename[.gz]|uri -> <stdout>
» open https://api.github.com/repos/lmorg/murex/issues -> foreach issue { out "$issue[number]: $issue[title]" }
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.
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 (
"path"
"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 {
return mimeToMurex(normalizeMime(mimeType))
}
func mimeToMurex(mime string) string {
// Check suffix
for suffix := range mimeSuffixes {
if strings.HasSuffix(mime, suffix) {
return mimeSuffixes[suffix]
}
}
// Find a direct match
dt := mimes[mime]
if dt != "" {
return dt
}
// No matches 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":
return types.Generic
default:
// Mime type not recognized so lets just make it a generic
return types.Generic
}
}
// RequestToMurex attempts to pick a data type for the content of
// a downloaded file using the value of the Content-Type header
// or, if not, the filename. If neither can be used to infer a
// usable data type, types.Generic is returned.
func RequestMetadataToMurex(contentType string, filename string) string {
contentType = normalizeMime(contentType)
if !(contentType == "" || contentType == "text/plain") {
foundType := mimeToMurex(contentType)
// MimeToMurex will return Generic when it can't find
// any other matches, but in that case we still want
// to check the filename ext if possible
if foundType != types.Generic {
return foundType
}
}
if filename != "" {
ext := strings.ToLower(strings.TrimPrefix(path.Ext(filename), "."))
knownType, foundType := GetFileExts()[ext]
if foundType {
return knownType
}
}
return types.Generic
}
// NormalizeMime prepares a mime type for processing by removing charset
// information, trimming leading/trailing spaces, and making it lower case
func normalizeMime(rawMimeType string) string {
mime := strings.Split(rawMimeType, ";")[0]
mime = strings.TrimSpace(mime)
mime = strings.ToLower(mime)
return mime
}
// 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]
}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"
}
}
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
openopen” (openagent): Creates a handler
function for opengetfile: Makes a standard HTTP request and return the
contents as Murex-aware data type for passing along Murex
pipelines.exec: Runs an executablefexec: Execute a command or function, bypassing the
usual order of precedence.foreach: Iterate through an arrayget: Makes a standard HTTP request and returns the
result as a JSON objectpost: HTTP POST request with a JSON-parsable
returnout: Print a string to the stdout with a trailing new
line characterconfig: Query or define Murex runtime settings* (generic): generic
(primitive)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 Fri Oct 24 08:59:31 UTC 2025 against commit e59ab49e59ab49e1628d8546d2ad8ce5eb1150445f6a940.
Current version is 7.1.4143 (unknown) which has been verified against tests cases.