| 169 | } |
| 170 | |
| 171 | func splitFirstShellToken(command string) (string, string) { |
| 172 | cleaned := strings.TrimLeftFunc(command, unicode.IsSpace) |
| 173 | if cleaned == "" { |
| 174 | return "", "" |
| 175 | } |
| 176 | runes := []rune(cleaned) |
| 177 | inSingle := false |
| 178 | inDouble := false |
| 179 | i := 0 |
| 180 | n := len(runes) |
| 181 | for i < n { |
| 182 | ch := runes[i] |
| 183 | if ch == '\\' && i+1 < n { |
| 184 | i += 2 |
| 185 | continue |
| 186 | } |
| 187 | if ch == '\'' && !inDouble { |
| 188 | inSingle = !inSingle |
| 189 | } else if ch == '"' && !inSingle { |
| 190 | inDouble = !inDouble |
| 191 | } else if !inSingle && !inDouble && (ch == ' ' || ch == '\t') { |
| 192 | break |
| 193 | } |
| 194 | i += 1 |
| 195 | } |
| 196 | return string(runes[:i]), string(runes[i:]) |
| 197 | } |
| 198 | |
| 199 | func leadingEnvName(token string) string { |
| 200 | if !strings.Contains(token, "=") { |