command_fs_mv.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package shell
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  8. )
  9. func init() {
  10. Commands = append(Commands, &commandFsMv{})
  11. }
  12. type commandFsMv struct {
  13. }
  14. func (c *commandFsMv) Name() string {
  15. return "fs.mv"
  16. }
  17. func (c *commandFsMv) Help() string {
  18. return `move or rename a file or a folder
  19. fs.mv <source entry> <destination entry>
  20. fs.mv /dir/file_name /dir2/filename2
  21. fs.mv /dir/file_name /dir2
  22. fs.mv /dir/dir2 /dir3/dir4/
  23. fs.mv /dir/dir2 /dir3/new_dir
  24. `
  25. }
  26. func (c *commandFsMv) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
  27. if len(args) != 2 {
  28. return fmt.Errorf("need to have 2 arguments")
  29. }
  30. sourcePath, err := commandEnv.parseUrl(args[0])
  31. if err != nil {
  32. return err
  33. }
  34. destinationPath, err := commandEnv.parseUrl(args[1])
  35. if err != nil {
  36. return err
  37. }
  38. sourceDir, sourceName := util.FullPath(sourcePath).DirAndName()
  39. destinationDir, destinationName := util.FullPath(destinationPath).DirAndName()
  40. return commandEnv.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  41. // collect destination entry info
  42. destinationRequest := &filer_pb.LookupDirectoryEntryRequest{
  43. Name: destinationDir,
  44. Directory: destinationName,
  45. }
  46. respDestinationLookupEntry, err := filer_pb.LookupEntry(client, destinationRequest)
  47. var targetDir, targetName string
  48. // moving a file or folder
  49. if err == nil && respDestinationLookupEntry.Entry.IsDirectory {
  50. // to a directory
  51. targetDir = util.Join(destinationDir, destinationName)
  52. targetName = sourceName
  53. } else {
  54. // to a file or folder
  55. targetDir = destinationDir
  56. targetName = destinationName
  57. }
  58. request := &filer_pb.AtomicRenameEntryRequest{
  59. OldDirectory: sourceDir,
  60. OldName: sourceName,
  61. NewDirectory: targetDir,
  62. NewName: targetName,
  63. }
  64. _, err = client.AtomicRenameEntry(context.Background(), request)
  65. fmt.Fprintf(writer, "move: %s => %s\n", sourcePath, util.NewFullPath(targetDir, targetName))
  66. return err
  67. })
  68. }