@@ -3,6 +3,7 @@ package hostagent
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "strings"
6
7
"time"
7
8
8
9
"github.com/lima-vm/lima/pkg/limayaml"
@@ -61,14 +62,17 @@ func (a *HostAgent) waitForRequirements(label string, requirements []requirement
61
62
// EOF
62
63
// /usr/bin/env ruby
63
64
//
64
- // ssh.ExecuteScript will strip the `#!` prefix from the first line and invoke the rest
65
- // of the line as the command. The full script is then passed via STDIN. We use the $' '
66
- // form of shell quoting to be able to use \n as newline escapes to fit everything on a
65
+ // ssh.ExecuteScript will strip the `#!` prefix from the first line and invoke the
66
+ // rest of the line as the command. The full script is then passed via STDIN. We use
67
+ // "$(printf '…')" to be able to use \n as newline escapes, to fit everything on a
67
68
// single line:
68
69
//
69
- // #!/bin/bash -c $ 'while … done<<EOF\n$(sudo …)\nEOF\n/usr/bin/env ruby'
70
+ // #!/bin/bash -c "$(printf 'while … done<<EOF\n$(sudo …)\nEOF\n/usr/bin/env ruby')"
70
71
// #!/usr/bin/env ruby
71
72
// …
73
+ //
74
+ // An earlier implementation used $'…' for quoting, but that isn't supported if the
75
+ // user switched the default shell to fish.
72
76
func prefixExportParam (script string ) (string , error ) {
73
77
interpreter , err := ssh .ParseScriptInterpreter (script )
74
78
if err != nil {
@@ -77,7 +81,14 @@ func prefixExportParam(script string) (string, error) {
77
81
78
82
// TODO we should have a symbolic constant for `/mnt/lima-cidata`
79
83
exportParam := `while read -r line; do [ -n "$line" ] && export "$line"; done<<EOF\n$(sudo cat /mnt/lima-cidata/param.env)\nEOF\n`
80
- return fmt .Sprintf ("#!/bin/bash -c $'%s%s'\n %s" , exportParam , interpreter , script ), nil
84
+
85
+ // double up all '%' characters so we can pass them through unchanged in the format string of printf
86
+ interpreter = strings .ReplaceAll (interpreter , "%" , "%%" )
87
+ exportParam = strings .ReplaceAll (exportParam , "%" , "%%" )
88
+ // strings will be interpolated into single-quoted strings, so protect any existing single quotes
89
+ interpreter = strings .ReplaceAll (interpreter , "'" , `'"'"'` )
90
+ exportParam = strings .ReplaceAll (exportParam , "'" , `'"'"'` )
91
+ return fmt .Sprintf ("#!/bin/bash -c \" $(printf '%s%s')\" \n %s" , exportParam , interpreter , script ), nil
81
92
}
82
93
83
94
func (a * HostAgent ) waitForRequirement (r requirement ) error {
0 commit comments