package shell import ( "context" "fmt" "io" "path/filepath" "github.com/chrislusf/seaweedfs/weed/filer2" "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" ) func init() { Commands = append(Commands, &commandFsMv{}) } type commandFsMv struct { } func (c *commandFsMv) Name() string { return "fs.mv" } func (c *commandFsMv) Help() string { return `move or rename a file or a folder fs.mv fs.mv /dir/file_name /dir2/filename2 fs.mv /dir/file_name /dir2 fs.mv /dir/dir2 /dir3/dir4/ fs.mv /dir/dir2 /dir3/new_dir ` } func (c *commandFsMv) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) { filerServer, filerPort, sourcePath, err := commandEnv.parseUrl(args[0]) if err != nil { return err } _, _, destinationPath, err := commandEnv.parseUrl(args[1]) if err != nil { return err } ctx := context.Background() sourceDir, sourceName := filer2.FullPath(sourcePath).DirAndName() destinationDir, destinationName := filer2.FullPath(destinationPath).DirAndName() return commandEnv.withFilerClient(ctx, filerServer, filerPort, func(ctx context.Context, client filer_pb.SeaweedFilerClient) error { // collect destination entry info destinationRequest := &filer_pb.LookupDirectoryEntryRequest{ Name: destinationDir, Directory: destinationName, } respDestinationLookupEntry, err := client.LookupDirectoryEntry(ctx, destinationRequest) var targetDir, targetName string // moving a file or folder if err == nil && respDestinationLookupEntry.Entry!= nil && respDestinationLookupEntry.Entry.IsDirectory { // to a directory targetDir = filepath.ToSlash(filepath.Join(destinationDir, destinationName)) targetName = sourceName } else { // to a file or folder targetDir = destinationDir targetName = destinationName } request := &filer_pb.AtomicRenameEntryRequest{ OldDirectory: sourceDir, OldName: sourceName, NewDirectory: targetDir, NewName: targetName, } _, err = client.AtomicRenameEntry(ctx, request) fmt.Fprintf(writer, "move: %s => %s\n", sourcePath, filer2.NewFullPath(targetDir, targetName)) return err }) }