Skip to content

Commit

Permalink
Allow use of bash as a script interpreter
Browse files Browse the repository at this point in the history
For #24470.
  • Loading branch information
iansltx committed Jan 15, 2025
1 parent 6977ec9 commit 6fa4b3e
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 7 deletions.
1 change: 1 addition & 0 deletions changes/24470-bash
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Added bash interpreter support for script execution
4 changes: 2 additions & 2 deletions cmd/fleetctl/scripts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ hello world
{
name: "invalid hashbang",
scriptPath: func() string { return writeTmpScriptContents(t, "#! /foo/bar", ".sh") },
expectErrMsg: `Interpreter not supported. Shell scripts must run in "#!/bin/sh" or "#!/bin/zsh."`,
expectErrMsg: `Interpreter not supported. Shell scripts must run in "#!/bin/sh", "#!/bin/bash", or "#!/bin/zsh."`,
},
{
name: "unsupported hashbang",
scriptPath: func() string { return writeTmpScriptContents(t, "#!/bin/ksh", ".sh") },
expectErrMsg: `Interpreter not supported. Shell scripts must run in "#!/bin/sh" or "#!/bin/zsh."`,
expectErrMsg: `Interpreter not supported. Shell scripts must run in "#!/bin/sh", "#!/bin/bash", or "#!/bin/zsh."`,
},
{
name: "posix shell hashbang",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const ScriptPackageUploader = ({
className={baseClass}
graphicName={["file-sh", "file-ps1"]}
message="Shell (.sh) for macOS and Linux or PowerShell (.ps1) for Windows"
additionalInfo="Script will run with “#!/bin/sh” or “#!/bin/zsh” on macOS and Linux."
additionalInfo="Script will run with “#!/bin/sh”, “#!/bin/zsh”, or “#!/bin/bash” on macOS and Linux."
accept=".sh,.ps1"
onFileUpload={onUploadFile}
isLoading={showLoading}
Expand Down
7 changes: 7 additions & 0 deletions orbit/pkg/scripts/exec_nonwindows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import (

func TestExecCmdNonWindows(t *testing.T) {
zshPath := "/bin/zsh"
bashPath := "/bin/bash"
if runtime.GOOS == "linux" {
zshPath = "/usr/bin/zsh"
bashPath = "/usr/bin/bash"
}

tests := []struct {
Expand All @@ -40,6 +42,11 @@ func TestExecCmdNonWindows(t *testing.T) {
contents: "#!/bin/sh\n[ -z \"$ZSH_VERSION\" ] && echo 1",
output: "1",
},
{
name: "bash shebang",
contents: "#!" + bashPath + "\n[ -z \"$ZSH_VERSION\" ] && echo 1",
output: "1",
},
{
name: "zsh shebang",
contents: "#!" + zshPath + "\n[ -n \"$ZSH_VERSION\" ] && echo 1",
Expand Down
6 changes: 3 additions & 3 deletions server/fleet/scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ const (

// anchored, so that it matches to the end of the line
var (
scriptHashbangValidation = regexp.MustCompile(`^#!\s*(:?/usr)?/bin/z?sh(?:\s*|\s+.*)$`)
ErrUnsupportedInterpreter = errors.New(`Interpreter not supported. Shell scripts must run in "#!/bin/sh" or "#!/bin/zsh."`)
scriptHashbangValidation = regexp.MustCompile(`^#!\s*(:?/usr)?/bin/(ba|z)?sh(?:\s*|\s+.*)$`)
ErrUnsupportedInterpreter = errors.New(`Interpreter not supported. Shell scripts must run in "#!/bin/sh", "#!/bin/bash", or "#!/bin/zsh."`)
)

// ValidateShebang validates if we support a script, and whether we
Expand All @@ -327,7 +327,7 @@ func ValidateShebang(s string) (directExecute bool, err error) {
if strings.HasPrefix(s, "#!") {
// read the first line in a portable way
s := bufio.NewScanner(strings.NewReader(s))
// if a hashbang is present, it can only be `/bin/sh` or `(/usr)/bin/zsh` for now
// if a hashbang is present, it can only be `(/usr)/bin/sh`, `(/usr)/bin/bash`, `(/usr)/bin/zsh` for now
if s.Scan() && !scriptHashbangValidation.MatchString(s.Text()) {
return false, ErrUnsupportedInterpreter
}
Expand Down
5 changes: 5 additions & 0 deletions server/fleet/scripts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ func TestValidateShebang(t *testing.T) {
contents: "#!/bin/zsh\necho hi",
directExecute: true,
},
{
name: "bash shebang",
contents: "#!/bin/bash\necho hi",
directExecute: true,
},
{
name: "zsh shebang with args",
contents: "#!/bin/zsh -x\necho hi",
Expand Down
5 changes: 4 additions & 1 deletion server/service/scripts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,15 @@ func TestHostRunScript(t *testing.T) {
{"invalid utf8", "\xff\xfa", "Wrong data format."},
{"valid without hashbang", "echo 'a'", ""},
{"valid with posix hashbang", "#!/bin/sh\necho 'a'", ""},
{"valid with usr bash hashbang", "#!/usr/bin/bash\necho 'a'", ""},
{"valid with bash hashbang", "#!/bin/bash\necho 'a'", ""},
{"valid with bash hashbang and arguments", "#!/bin/bash -x\necho 'a'", ""},
{"valid with usr zsh hashbang", "#!/usr/bin/zsh\necho 'a'", ""},
{"valid with zsh hashbang", "#!/bin/zsh\necho 'a'", ""},
{"valid with zsh hashbang and arguments", "#!/bin/zsh -x\necho 'a'", ""},
{"valid with hashbang and spacing", "#! /bin/sh \necho 'a'", ""},
{"valid with hashbang and Windows newline", "#! /bin/sh \r\necho 'a'", ""},
{"invalid hashbang", "#!/bin/bash\necho 'a'", "Interpreter not supported."},
{"invalid hashbang", "#!/bin/ksh\necho 'a'", "Interpreter not supported."},
}

ctx = viewer.NewContext(ctx, viewer.Viewer{User: test.UserAdmin})
Expand Down

0 comments on commit 6fa4b3e

Please sign in to comment.