github.com/pkg/sftp@v1.13.6/example_test.go (about)

     1  package sftp_test
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  	"os/exec"
    10  	"path"
    11  	"strings"
    12  
    13  	"github.com/pkg/sftp"
    14  	"golang.org/x/crypto/ssh"
    15  )
    16  
    17  func Example() {
    18  	var conn *ssh.Client
    19  
    20  	// open an SFTP session over an existing ssh connection.
    21  	client, err := sftp.NewClient(conn)
    22  	if err != nil {
    23  		log.Fatal(err)
    24  	}
    25  	defer client.Close()
    26  
    27  	// walk a directory
    28  	w := client.Walk("/home/user")
    29  	for w.Step() {
    30  		if w.Err() != nil {
    31  			continue
    32  		}
    33  		log.Println(w.Path())
    34  	}
    35  
    36  	// leave your mark
    37  	f, err := client.Create("hello.txt")
    38  	if err != nil {
    39  		log.Fatal(err)
    40  	}
    41  	if _, err := f.Write([]byte("Hello world!")); err != nil {
    42  		log.Fatal(err)
    43  	}
    44  	f.Close()
    45  
    46  	// check it's there
    47  	fi, err := client.Lstat("hello.txt")
    48  	if err != nil {
    49  		log.Fatal(err)
    50  	}
    51  	log.Println(fi)
    52  }
    53  
    54  func ExampleNewClientPipe() {
    55  	// Connect to a remote host and request the sftp subsystem via the 'ssh'
    56  	// command.  This assumes that passwordless login is correctly configured.
    57  	cmd := exec.Command("ssh", "example.com", "-s", "sftp")
    58  
    59  	// send errors from ssh to stderr
    60  	cmd.Stderr = os.Stderr
    61  
    62  	// get stdin and stdout
    63  	wr, err := cmd.StdinPipe()
    64  	if err != nil {
    65  		log.Fatal(err)
    66  	}
    67  	rd, err := cmd.StdoutPipe()
    68  	if err != nil {
    69  		log.Fatal(err)
    70  	}
    71  
    72  	// start the process
    73  	if err := cmd.Start(); err != nil {
    74  		log.Fatal(err)
    75  	}
    76  	defer cmd.Wait()
    77  
    78  	// open the SFTP session
    79  	client, err := sftp.NewClientPipe(rd, wr)
    80  	if err != nil {
    81  		log.Fatal(err)
    82  	}
    83  
    84  	// read a directory
    85  	list, err := client.ReadDir("/")
    86  	if err != nil {
    87  		log.Fatal(err)
    88  	}
    89  
    90  	// print contents
    91  	for _, item := range list {
    92  		fmt.Println(item.Name())
    93  	}
    94  
    95  	// close the connection
    96  	client.Close()
    97  }
    98  
    99  func ExampleClient_Mkdir_parents() {
   100  	// Example of mimicing 'mkdir --parents'; I.E. recursively create
   101  	// directoryies and don't error if any directories already exists.
   102  	var conn *ssh.Client
   103  
   104  	client, err := sftp.NewClient(conn)
   105  	if err != nil {
   106  		log.Fatal(err)
   107  	}
   108  	defer client.Close()
   109  
   110  	sshFxFailure := uint32(4)
   111  	mkdirParents := func(client *sftp.Client, dir string) (err error) {
   112  		var parents string
   113  
   114  		if path.IsAbs(dir) {
   115  			// Otherwise, an absolute path given below would be turned in to a relative one
   116  			// by splitting on "/"
   117  			parents = "/"
   118  		}
   119  
   120  		for _, name := range strings.Split(dir, "/") {
   121  			if name == "" {
   122  				// Paths with double-/ in them should just move along
   123  				// this will also catch the case of the first character being a "/", i.e. an absolute path
   124  				continue
   125  			}
   126  			parents = path.Join(parents, name)
   127  			err = client.Mkdir(parents)
   128  			if status, ok := err.(*sftp.StatusError); ok {
   129  				if status.Code == sshFxFailure {
   130  					var fi os.FileInfo
   131  					fi, err = client.Stat(parents)
   132  					if err == nil {
   133  						if !fi.IsDir() {
   134  							return fmt.Errorf("file exists: %s", parents)
   135  						}
   136  					}
   137  				}
   138  			}
   139  			if err != nil {
   140  				break
   141  			}
   142  		}
   143  		return err
   144  	}
   145  
   146  	err = mkdirParents(client, "/tmp/foo/bar")
   147  	if err != nil {
   148  		log.Fatal(err)
   149  	}
   150  }
   151  
   152  func ExampleFile_ReadFrom_bufio() {
   153  	// Using Bufio to buffer writes going to an sftp.File won't buffer as it
   154  	// skips buffering if the underlying writer support ReadFrom. The
   155  	// workaround is to wrap your writer in a struct that only implements
   156  	// io.Writer.
   157  	//
   158  	// For background see github.com/pkg/sftp/issues/125
   159  
   160  	var data_source io.Reader
   161  	var f *sftp.File
   162  	type writerOnly struct{ io.Writer }
   163  	bw := bufio.NewWriter(writerOnly{f}) // no ReadFrom()
   164  	bw.ReadFrom(data_source)
   165  }