Documentation
¶
Overview ¶
Package shellescape provides the shellescape.Quote to escape arbitrary strings for a safe use as command line arguments in the most common POSIX shells.
The original Python package which this work was inspired by can be found at https://pypi.python.org/pypi/shellescape.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Quote ¶
Quote returns a shell-escaped version of the string s. The returned value is a string that can safely be used as one token in a shell command line.
Example ¶
package main
import (
"fmt"
"strings"
"al.essio.dev/pkg/shellescape"
)
func main() {
filename := "myfile; rm -rf /"
prog := "/bin/ls -lh"
unsafe := strings.Join([]string{prog, filename}, " ")
safe := strings.Join([]string{prog, shellescape.Quote(filename)}, " ")
fmt.Println("unsafe:", unsafe)
fmt.Println("safe:", safe)
for i, part := range strings.Split(unsafe, " ") {
fmt.Printf("unsafe[%d] = %s\n", i, part)
}
for i, part := range strings.Split(safe, " ") {
fmt.Printf("safe[%d] = %s\n", i, part)
}
}
Output: unsafe: /bin/ls -lh myfile; rm -rf / safe: /bin/ls -lh 'myfile; rm -rf /' unsafe[0] = /bin/ls unsafe[1] = -lh unsafe[2] = myfile; unsafe[3] = rm unsafe[4] = -rf unsafe[5] = / safe[0] = /bin/ls safe[1] = -lh safe[2] = 'myfile; safe[3] = rm safe[4] = -rf safe[5] = /'
func QuoteCommand ¶
QuoteCommand returns a shell-escaped version of the slice of strings. The returned value is a string that can safely be used as shell command arguments.
Example ¶
package main
import (
"fmt"
"github.com/google/shlex"
"al.essio.dev/pkg/shellescape"
)
func main() {
filename := "myfile; rm -rf /"
unsafe := fmt.Sprintf("ls -l %s", filename)
command := fmt.Sprintf("ls -l %s", shellescape.Quote(filename))
splitCommand, _ := shlex.Split(command)
fmt.Println("unsafe:", unsafe)
fmt.Println("command:", command)
fmt.Println("splitCommand:", splitCommand)
remoteCommandUnsafe := fmt.Sprintf("ssh host.domain %s", command)
remoteCommand := fmt.Sprintf("ssh host.domain %s", shellescape.Quote(command))
splitRemoteCommand, _ := shlex.Split(remoteCommand)
fmt.Println("remoteCommandUnsafe:", remoteCommandUnsafe)
fmt.Println("remoteCommand:", remoteCommand)
fmt.Println("splitRemoteCommand:", splitRemoteCommand)
lastSplit, _ := shlex.Split(splitRemoteCommand[2])
fmt.Println("lastSplit[0]:", lastSplit[0])
fmt.Println("lastSplit[1]:", lastSplit[1])
fmt.Println("lastSplit[2]:", lastSplit[2])
}
Output: unsafe: ls -l myfile; rm -rf / command: ls -l 'myfile; rm -rf /' splitCommand: [ls -l myfile; rm -rf /] remoteCommandUnsafe: ssh host.domain ls -l 'myfile; rm -rf /' remoteCommand: ssh host.domain 'ls -l '"'"'myfile; rm -rf /'"'"'' splitRemoteCommand: [ssh host.domain ls -l 'myfile; rm -rf /'] lastSplit[0]: ls lastSplit[1]: -l lastSplit[2]: myfile; rm -rf /
Example (Simple) ¶
package main
import (
"fmt"
"strings"
"al.essio.dev/pkg/shellescape"
)
func main() {
filename := "filename with space"
prog := "/usr/bin/ls"
args := "-lh"
unsafe := strings.Join([]string{prog, args, filename}, " ")
safe := strings.Join([]string{prog, shellescape.QuoteCommand([]string{args, filename})}, " ")
fmt.Println("unsafe:", unsafe)
fmt.Println("safe:", safe)
}
Output: unsafe: /usr/bin/ls -lh filename with space safe: /usr/bin/ls -lh 'filename with space'
func ScanTokens ¶ added in v1.6.0
ScanTokens is a split function for a bufio.Scanner that returns each word of text, stripped of amy trailing end-of-text empty byte.
Example ¶
package main
import (
"bufio"
"fmt"
"strings"
"al.essio.dev/pkg/shellescape"
)
func main() {
words := "'tis\x00but\x00a\x00scratch!\x00"
scanner := bufio.NewScanner(strings.NewReader(words))
scanner.Split(shellescape.ScanTokens)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
Output: 'tis but a scratch!
func StripUnsafe ¶
StripUnsafe remove non-printable runes, e.g. control characters in a string that is meant for consumption by terminals that support control characters.
Example ¶
package main
import (
"fmt"
"al.essio.dev/pkg/shellescape"
)
func main() {
safeString := `"printable!" #$%^characters '' 12321312"`
unsafeString := "these runes shall be removed: \u0000\u0081\u001f"
fmt.Println("safe:", shellescape.StripUnsafe(safeString))
fmt.Println("unsafe:", shellescape.StripUnsafe(unsafeString))
}
Output: safe: "printable!" #$%^characters '' 12321312" unsafe: these runes shall be removed:
Types ¶
This section is empty.