(command string)
| 97 | } |
| 98 | |
| 99 | func SplitPipeline(command string) []string { |
| 100 | var segments []string |
| 101 | var current []rune |
| 102 | inSingle := false |
| 103 | inDouble := false |
| 104 | i := 0 |
| 105 | runes := []rune(command) |
| 106 | n := len(runes) |
| 107 | for i < n { |
| 108 | ch := runes[i] |
| 109 | if ch == '\\' && i+1 < n { |
| 110 | current = append(current, ch) |
| 111 | current = append(current, runes[i+1]) |
| 112 | i += 2 |
| 113 | continue |
| 114 | } else if ch == '\'' && !inDouble { |
| 115 | inSingle = !inSingle |
| 116 | } else if ch == '"' && !inSingle { |
| 117 | inDouble = !inDouble |
| 118 | } else if !inSingle && !inDouble { |
| 119 | towChar := "" |
| 120 | if i+2 <= n { |
| 121 | towChar = string(runes[i : i+2]) |
| 122 | } |
| 123 | if towChar == "||" || towChar == "&&" { |
| 124 | seg := strings.TrimSpace(string(current)) |
| 125 | if seg != "" { |
| 126 | segments = append(segments, seg) |
| 127 | } |
| 128 | current = []rune{} |
| 129 | i += 2 |
| 130 | continue |
| 131 | } |
| 132 | if ch == ';' || ch == '|' { |
| 133 | seg := strings.TrimSpace(string(current)) |
| 134 | if seg != "" { |
| 135 | segments = append(segments, seg) |
| 136 | } |
| 137 | current = []rune{} |
| 138 | i += 1 |
| 139 | continue |
| 140 | } |
| 141 | if ch == '&' { |
| 142 | prev := []rune(strings.TrimRightFunc(string(current), unicode.IsSpace)) |
| 143 | prevIsRedirect := len(prev) > 0 && (prev[len(prev)-1] == '>' || prev[len(prev)-1] == '<') |
| 144 | if prevIsRedirect || (i+1 < n && runes[i+1] == '>') { |
| 145 | current = append(current, ch) |
| 146 | i += 1 |
| 147 | continue |
| 148 | } |
| 149 | seg := strings.TrimSpace(string(current)) |
| 150 | if seg != "" { |
| 151 | segments = append(segments, seg) |
| 152 | } |
| 153 | current = []rune{} |
| 154 | i += 1 |
| 155 | continue |
| 156 | } |
no outgoing calls