mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-23 18:21:28 +00:00
* fix(weed/shell): suppress prompt when stdin or stdout is not a TTY When piping weed shell output (e.g. `echo "s3.user.list" | weed shell | jq`), the "> " prompt was written to stdout, breaking JSON parsers. `liner.TerminalSupported()` only checks platform support, not whether stdin/stdout are actual TTYs. Add explicit checks using `term.IsTerminal()` so the shell falls back to the non-interactive scanner path when piped. Fixes #8962 * fix(weed/shell): suppress informational logs unless -verbose is set Suppress glog info messages and connection status logs on stderr by default. Add -verbose flag to opt in to the previous noisy behavior. This keeps piped output clean (e.g. `echo "s3.user.list" | weed shell | jq`). * fix(weed/shell): defer liner init until after TTY check Move liner.NewLiner() and related setup (history, completion, interrupt handler) inside the interactive block so the terminal is not put into raw mode when stdout is redirected. Previously, liner would set raw mode unconditionally at startup, leaving the terminal broken when falling back to the scanner path. Addresses review feedback from gemini-code-assist. * refactor(weed/shell): consolidate verbose logging into single block Group all verbose stderr output within one conditional block instead of scattering three separate if-verbose checks around the filer logic. Addresses review feedback from gemini-code-assist. * fix(weed/shell): clean up global liner state and suppress logtostderr - Set line=nil after Close() to prevent stale state if RunShell is called again (e.g. in tests) - Add nil check in OnInterrupt handler for non-interactive sessions - Also set logtostderr=false when not verbose, in case it was enabled Addresses review feedback from gemini-code-assist. * refactor(weed/shell): make liner state local to eliminate data race Replace the package-level `line` variable with a local variable in RunShell, passing it explicitly to setCompletionHandler, loadHistory, and saveHistory. This eliminates a data race between the OnInterrupt goroutine and the defer that previously set the global to nil. Addresses review feedback from gemini-code-assist. * rename(weed/shell): rename -verbose flag to -debug Avoid conflict with -verbose flags already used by individual shell commands (e.g. ec.encode, volume.fix.replication, volume.check.disk).
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/security"
|
|
"github.com/seaweedfs/seaweedfs/weed/shell"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
)
|
|
|
|
var (
|
|
shellOptions shell.ShellOptions
|
|
shellInitialFiler *string
|
|
shellCluster *string
|
|
shellDebug *bool
|
|
)
|
|
|
|
func init() {
|
|
cmdShell.Run = runShell // break init cycle
|
|
shellOptions.Masters = cmdShell.Flag.String("master", "", "comma-separated master servers, e.g. localhost:9333")
|
|
shellOptions.FilerGroup = cmdShell.Flag.String("filerGroup", "", "filerGroup for the filers")
|
|
shellInitialFiler = cmdShell.Flag.String("filer", "", "filer host and port for initial connection, e.g. localhost:8888")
|
|
shellCluster = cmdShell.Flag.String("cluster", "", "cluster defined in shell.toml")
|
|
shellDebug = cmdShell.Flag.Bool("debug", false, "print informational logs to stderr")
|
|
}
|
|
|
|
var cmdShell = &Command{
|
|
UsageLine: "shell",
|
|
Short: "run interactive administrative commands",
|
|
Long: `run interactive administrative commands.
|
|
|
|
Generate shell.toml via "weed scaffold -config=shell"
|
|
|
|
`,
|
|
}
|
|
|
|
func runShell(command *Command, args []string) bool {
|
|
|
|
util.LoadSecurityConfiguration()
|
|
shellOptions.GrpcDialOption = security.LoadClientTLS(util.GetViper(), "grpc.client")
|
|
shellOptions.Directory = "/"
|
|
|
|
util.LoadConfiguration("shell", false)
|
|
viper := util.GetViper()
|
|
cluster := viper.GetString("cluster.default")
|
|
if *shellCluster != "" {
|
|
cluster = *shellCluster
|
|
}
|
|
|
|
if *shellOptions.Masters == "" {
|
|
if cluster == "" {
|
|
*shellOptions.Masters = "localhost:9333"
|
|
} else {
|
|
*shellOptions.Masters = viper.GetString("cluster." + cluster + ".master")
|
|
}
|
|
}
|
|
|
|
filerAddress := *shellInitialFiler
|
|
if filerAddress == "" && cluster != "" {
|
|
filerAddress = viper.GetString("cluster." + cluster + ".filer")
|
|
}
|
|
shellOptions.FilerAddress = pb.ServerAddress(filerAddress)
|
|
shellOptions.Debug = *shellDebug
|
|
if shellOptions.Debug {
|
|
fmt.Fprintf(os.Stderr, "master: %s filer: %s\n", *shellOptions.Masters, shellOptions.FilerAddress)
|
|
}
|
|
|
|
shell.RunShell(shellOptions)
|
|
|
|
return true
|
|
|
|
}
|