@@ -96,6 +96,24 @@ You can configure OpenCode using environment variables:
| `AZURE_OPENAI_ENDPOINT` | For Azure OpenAI models |
| `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) |
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models |
+| `SHELL` | Default shell to use (if not specified in config) |
+
+### Shell Configuration
+
+OpenCode allows you to configure the shell used by the bash tool. By default, it uses the shell specified in the `SHELL` environment variable, or falls back to `/bin/bash` if not set.
+
+You can override this in your configuration file:
+
+```json
+{
+ "shell": {
+ "path": "/bin/zsh",
+ "args": ["-l"]
+ }
+}
+```
+
+This is useful if you want to use a different shell than your default system shell, or if you need to pass specific arguments to the shell.
### Configuration File Structure
@@ -136,6 +154,10 @@ You can configure OpenCode using environment variables:
"maxTokens": 80
}
},
+ "shell": {
+ "path": "/bin/bash",
+ "args": ["-l"]
+ },
"mcpServers": {
"example": {
"type": "stdio",
@@ -73,6 +73,12 @@ type TUIConfig struct {
Theme string `json:"theme,omitempty"`
}
+// ShellConfig defines the configuration for the shell used by the bash tool.
+type ShellConfig struct {
+ Path string `json:"path,omitempty"`
+ Args []string `json:"args,omitempty"`
+}
+
// Config is the main configuration structure for the application.
type Config struct {
Data Data `json:"data"`
@@ -85,6 +91,7 @@ type Config struct {
DebugLSP bool `json:"debugLSP,omitempty"`
ContextPaths []string `json:"contextPaths,omitempty"`
TUI TUIConfig `json:"tui"`
+ Shell ShellConfig `json:"shell,omitempty"`
AutoCompact bool `json:"autoCompact,omitempty"`
}
@@ -217,6 +224,14 @@ func setDefaults(debug bool) {
viper.SetDefault("tui.theme", "opencode")
viper.SetDefault("autoCompact", true)
+ // Set default shell from environment or fallback to /bin/bash
+ shellPath := os.Getenv("SHELL")
+ if shellPath == "" {
+ shellPath = "/bin/bash"
+ }
+ viper.SetDefault("shell.path", shellPath)
+ viper.SetDefault("shell.args", []string{"-l"})
+
if debug {
viper.SetDefault("debug", true)
viper.Set("log.level", "debug")
@@ -11,6 +11,8 @@ import (
"sync"
"syscall"
"time"
+
+ "github.com/opencode-ai/opencode/internal/config"
)
type PersistentShell struct {
@@ -57,12 +59,31 @@ func GetPersistentShell(workingDir string) *PersistentShell {
}
func newPersistentShell(cwd string) *PersistentShell {
- shellPath := os.Getenv("SHELL")
+ // Get shell configuration from config
+ cfg := config.Get()
+
+ // Default to environment variable if config is not set or nil
+ var shellPath string
+ var shellArgs []string
+
+ if cfg != nil {
+ shellPath = cfg.Shell.Path
+ shellArgs = cfg.Shell.Args
+ }
+
if shellPath == "" {
- shellPath = "/bin/bash"
+ shellPath = os.Getenv("SHELL")
+ if shellPath == "" {
+ shellPath = "/bin/bash"
+ }
+ }
+
+ // Default shell args
+ if len(shellArgs) == 0 {
+ shellArgs = []string{"-l"}
}
- cmd := exec.Command(shellPath, "-l")
+ cmd := exec.Command(shellPath, shellArgs...)
cmd.Dir = cwd
stdinPipe, err := cmd.StdinPipe()