add assignments name=value and unset
- name=value (one or more) without a command sets variables of the shell - name=value before a command sets them only in its environment (for builtins only while they run) - an assignment needs an unquoted name and =; the value is not split and not expanded as wildcard or brace pattern, ~ is expanded after = and : - the status of an assignment is the one of its last $(...) - new builtin unset Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fb94e98da5
commit
22ce8c00d4
5 files changed
+256
-14
No files matched your search
@@ -22,6 +22,7 @@ func expandBraceWords(input string) (string, error) {
|
||||
var (
|
||||
out strings.Builder
|
||||
afterRedirect bool // the next word is the target of a redirection
|
||||
commandStart = true
|
||||
)
|
||||
|
||||
for i := 0; i < len(input); {
|
||||
@@ -33,6 +34,8 @@ func expandBraceWords(input string) (string, error) {
|
||||
case strings.IndexByte(";&|<>", ch) >= 0:
|
||||
if ch == '<' || ch == '>' {
|
||||
afterRedirect = true
|
||||
} else {
|
||||
commandStart = true
|
||||
}
|
||||
out.WriteByte(ch)
|
||||
i++
|
||||
@@ -42,6 +45,16 @@ func expandBraceWords(input string) (string, error) {
|
||||
return out.String(), nil
|
||||
default:
|
||||
end := wordEnd(input, i)
|
||||
if commandStart && !afterRedirect && isAssignment(input[i:end]) {
|
||||
// name=value before the command: no brace expansion, like
|
||||
// in bash
|
||||
out.WriteString(input[i:end])
|
||||
i = end
|
||||
continue
|
||||
}
|
||||
if !afterRedirect {
|
||||
commandStart = false
|
||||
}
|
||||
words, err := expandBraces(input[i:end])
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -57,6 +70,12 @@ func expandBraceWords(input string) (string, error) {
|
||||
return out.String(), nil
|
||||
}
|
||||
|
||||
// isAssignment reports whether a word starts with name= (unquoted).
|
||||
func isAssignment(word string) bool {
|
||||
name, _, ok := strings.Cut(word, "=")
|
||||
return ok && isVarName(name)
|
||||
}
|
||||
|
||||
// wordEnd returns the end of the word starting at i: the next unquoted blank
|
||||
// or operator character.
|
||||
func wordEnd(s string, i int) int {
|
||||
|
||||
Reference in new issue
Block a user