shelltoken

package module
v0.0.0-...-29095f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: MIT Imports: 2 Imported by: 3

README

shelltoken

Go Reference License Go Report Card CICD Pipeline

Go library to split a command line into env, command and arguments.

Installation

%> go get github.com/sni/shelltoken

Documentation

The documenation can be found on pkg.go.dev.

Example

package main

import (
	"fmt"

	"github.com/sni/shelltoken"
)

func ExampleSplitLinux() {
	env, argv, err := shelltoken.SplitLinux("PATH=/bin ls -l")
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("env:  %#v\nargv: %#v\n", env, argv)
	// Output:
	// env:  []string{"PATH=/bin"}
	// argv: []string{"ls", "-l"}
}

func ExampleSplitWindows() {
	env, argv, err := shelltoken.SplitWindows(`'C:\Program Files\Vim\vim90\vim.exe' -n test.txt`)
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("env:  %#v\nargv: %#v\n", env, argv)
	// Output:
	// env:  []string{}
	// argv: []string{"C:\\Program Files\\Vim\\vim90\\vim.exe", "-n", "test.txt"}
}

func ExampleSplitQuotes() {
	token, err := shelltoken.SplitQuotes(`ls -la | grep xyz;echo ok`, `|;`, shelltoken.SplitIgnoreShellCharacters|shelltoken.SplitKeepSeparator)
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("token: %#v\n", token)
	// Output:
	// token: []string{"ls -la ", "|", " grep xyz", ";", "echo ok"}
}

Documentation

Overview

Package shelltoken implements a command line tokenizer.

The shelltoken package splits a command line into token by whitespace characters while honoring single and double quotes. Backslashes and escaped quotes are supported as well. Whitespace is defined as " \t\n\r" Shell-characters within single quotes are "$`" Shell-characters within double quotes are "$`!&*()~[]|\{};<>?"

Index

Examples

Constants

View Source
const (
	Whitespace                  = " \t\n\r"
	DoubleQuoteShellCharacters  = "$`"
	OutsideQuoteShellCharacters = "$`!&*()~[]|{};<>?"
)

Variables

This section is empty.

Functions

func ExtractEnvFromArgv

func ExtractEnvFromArgv(argv []string) (envs, args []string)

ExtractEnvFromArgv splits list of arguments into env and args.

func SplitLinux

func SplitLinux(str string) (env, argv []string, err error)

SplitLinux will tokenize a string the way the linux /bin/sh would do. A successful parse will return the env list with parsed environment variable definitions along with the argv list. The argv list will always contain at least one element (which can be empty). The argv[0] contains the command and all following elements are the arguments. It uses - separator: " \t\n\r". - keep backslashes: false. - keep quotes: false. - keep separator: false. returns error if shell characters were found.

Example
package main

import (
	"fmt"

	"github.com/sni/shelltoken"
)

func main() {
	env, argv, err := shelltoken.SplitLinux("PATH=/bin ls -l")
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("env:  %#v\nargv: %#v\n", env, argv)
}
Output:

env:  []string{"PATH=/bin"}
argv: []string{"ls", "-l"}

func SplitQuotes

func SplitQuotes(str, sep string, options ...SplitOption) (argv []string, err error)

SplitQuotes will tokenize text into chunks honoring quotes. Options are a list of SplitOption(s) or a bitmask of SplitOption(s) An unsuccessful parse will return an error. The error will be either UnbalancedQuotesError or ShellCharactersFoundError.

Example
package main

import (
	"fmt"

	"github.com/sni/shelltoken"
)

func main() {
	token, err := shelltoken.SplitQuotes(`ls -la | grep xyz;echo ok`, `|;`, shelltoken.SplitIgnoreShellCharacters|shelltoken.SplitKeepSeparator)
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("token: %#v\n", token)
}
Output:

token: []string{"ls -la ", "|", " grep xyz", ";", "echo ok"}

func SplitWindows

func SplitWindows(str string) (env, argv []string, err error)

SplitWindows will tokenize a string the way windows would do. A successful parse will return the env list with parsed environment variable definitions along with the argv list. The argv list will always contain at least one element (which can be empty). The argv[0] contains the command and all following elements are the arguments. It uses - separator: " \t\n\r". - keep backslashes: true. - keep quotes: false. - keep separator: false. returns error if shell characters were found.

Example
package main

import (
	"fmt"

	"github.com/sni/shelltoken"
)

func main() {
	env, argv, err := shelltoken.SplitWindows(`'C:\Program Files\Vim\vim90\vim.exe' -n test.txt`)
	if err != nil {
		panic(err.Error())
	}

	fmt.Printf("env:  %#v\nargv: %#v\n", env, argv)
}
Output:

env:  []string{}
argv: []string{"C:\\Program Files\\Vim\\vim90\\vim.exe", "-n", "test.txt"}

Types

type ShellCharactersFoundError

type ShellCharactersFoundError struct {
	// contains filtered or unexported fields
}

func (*ShellCharactersFoundError) Error

func (e *ShellCharactersFoundError) Error() string

type SplitOption

type SplitOption uint8

SplitOption sets available parse options.

const (
	// SplitNoOptions is the zero value for options.
	SplitNoOptions SplitOption = 0

	// SplitKeepBackslashes: Do not remove backslashes.
	SplitKeepBackslashes SplitOption = 1 << iota

	// SplitIgnoreBackslashes does not escape characters by backslash.
	SplitIgnoreBackslashes

	// SplitKeepQuotes: Keep quotes in the final argv list.
	SplitKeepQuotes

	// SplitKeepSeparator: do not remove the split characters. They end up as a separate element in the argv list.
	SplitKeepSeparator

	// SplitStopOnShellCharacters cancels parsing upon the first shell character and returns ShellCharactersFoundError.
	SplitStopOnShellCharacters

	// SplitContinueOnShellCharacters returns ShellCharactersFoundError on shell characters but will parse to the end.
	SplitContinueOnShellCharacters

	// SplitIgnoreShellCharacters will ignore shell characters.
	SplitIgnoreShellCharacters

	// SplitKeepAndIgnoreAll just splits but keeps all characters.
	SplitKeepAll = SplitKeepQuotes | SplitKeepBackslashes | SplitKeepSeparator | SplitIgnoreShellCharacters
)

type UnbalancedQuotesError

type UnbalancedQuotesError struct{}

func (*UnbalancedQuotesError) Error

func (e *UnbalancedQuotesError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL