Implement the rclone cat command
This commit is contained in:
parent
f22029bf3d
commit
84eb7031bb
4 changed files with 90 additions and 0 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
// Active commands
|
||||
_ "github.com/ncw/rclone/cmd"
|
||||
_ "github.com/ncw/rclone/cmd/authorize"
|
||||
_ "github.com/ncw/rclone/cmd/cat"
|
||||
_ "github.com/ncw/rclone/cmd/check"
|
||||
_ "github.com/ncw/rclone/cmd/cleanup"
|
||||
_ "github.com/ncw/rclone/cmd/config"
|
||||
|
|
40
cmd/cat/cat.go
Normal file
40
cmd/cat/cat.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package cat
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ncw/rclone/cmd"
|
||||
"github.com/ncw/rclone/fs"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd.Root.AddCommand(catCmd)
|
||||
}
|
||||
|
||||
var catCmd = &cobra.Command{
|
||||
Use: "cat remote:path",
|
||||
Short: `Concatenates any files and sends them to stdout.`,
|
||||
Long: `
|
||||
rclone cat sends any files to standard output.
|
||||
|
||||
You can use it like this to output a single file
|
||||
|
||||
rclone cat remote:path/to/file
|
||||
|
||||
Or like this to output any file in dir or subdirectories.
|
||||
|
||||
rclone cat remote:path/to/dir
|
||||
|
||||
Or like this to output any .txt files in dir or subdirectories.
|
||||
|
||||
rclone --include "*.txt" cat remote:path/to/dir
|
||||
`,
|
||||
Run: func(command *cobra.Command, args []string) {
|
||||
cmd.CheckArgs(1, 1, command, args)
|
||||
fsrc := cmd.NewFsSrc(args)
|
||||
cmd.Run(false, command, func() error {
|
||||
return fs.Cat(fsrc, os.Stdout)
|
||||
})
|
||||
},
|
||||
}
|
|
@ -1012,3 +1012,34 @@ func CleanUp(f Fs) error {
|
|||
}
|
||||
return fc.CleanUp()
|
||||
}
|
||||
|
||||
// Cat any files to the io.Writer
|
||||
func Cat(f Fs, w io.Writer) error {
|
||||
var mu sync.Mutex
|
||||
return ListFn(f, func(o Object) {
|
||||
Stats.Transferring(o.Remote())
|
||||
defer Stats.DoneTransferring(o.Remote())
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
in, err := o.Open()
|
||||
if err != nil {
|
||||
Stats.Error()
|
||||
ErrorLog(o, "Failed to open: %v", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
err = in.Close()
|
||||
if err != nil {
|
||||
Stats.Error()
|
||||
ErrorLog(o, "Failed to close: %v", err)
|
||||
}
|
||||
}()
|
||||
inAccounted := NewAccount(in, o) // account the transfer
|
||||
_, err = io.Copy(w, inAccounted)
|
||||
if err != nil {
|
||||
Stats.Error()
|
||||
ErrorLog(o, "Failed to send to output: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -620,3 +620,21 @@ func TestDeduplicateRename(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCat(t *testing.T) {
|
||||
r := NewRun(t)
|
||||
defer r.Finalise()
|
||||
file1 := r.WriteBoth("file1", "aaa", t1)
|
||||
file2 := r.WriteBoth("file2", "bbb", t2)
|
||||
|
||||
fstest.CheckItems(t, r.fremote, file1, file2)
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := fs.Cat(r.fremote, &buf)
|
||||
require.NoError(t, err)
|
||||
res := buf.String()
|
||||
|
||||
if res != "aaabbb" && res != "bbbaaa" {
|
||||
t.Errorf("Incorrect output from Cat: %q", res)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue