diff --git a/cmd/cmd.go b/cmd/cmd.go index 01f0426db..5f1729401 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -66,6 +66,7 @@ const ( exitCodeNoRetryError exitCodeFatalError exitCodeTransferExceeded + exitCodeNoFilesTransferred ) // ShowVersion prints the version to stdout @@ -312,6 +313,7 @@ func Run(Retry bool, showStats bool, cmd *cobra.Command, f func() error) { } } resolveExitCode(cmdErr) + } // CheckArgs checks there are enough arguments and prints a message if not @@ -430,6 +432,11 @@ func initConfig() { func resolveExitCode(err error) { atexit.Run() if err == nil { + if fs.Config.ErrorOnNoTransfer { + if accounting.GlobalStats().GetTransfers() == 0 { + os.Exit(exitCodeNoFilesTransferred) + } + } os.Exit(exitCodeSuccess) } diff --git a/docs/content/docs.md b/docs/content/docs.md index b0027aae6..9791d744a 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -553,6 +553,18 @@ the time to send the request header. The default is `1s`. Set to 0 to disable. +### --error-on-no-transfer ### + +By default, rclone will exit with return code 0 if there were no errors. + +This option allows rclone to return exit code 9 if no files were transferred +between the source and destination. This allows using rclone in scripts, and +triggering follow-on actions if data was copied, or skipping if not. + +NB: Enabling this option turns a usually non-fatal error into a potentially +fatal one - please check and adjust your scripts accordingly! + + ### --ignore-case-sync ### Using this option will cause rclone to ignore the case of the files @@ -1622,6 +1634,7 @@ it will log a high priority message if the retry was successful. * `6` - Less serious errors (like 461 errors from dropbox) (NoRetry errors) * `7` - Fatal error (one that more retries won't fix, like account suspended) (Fatal errors) * `8` - Transfer exceeded - limit set by --max-transfer reached + * `9` - Operation successful, but no files transferred Environment Variables --------------------- diff --git a/fs/config.go b/fs/config.go index 285ac4024..4e3cc6a60 100644 --- a/fs/config.go +++ b/fs/config.go @@ -100,6 +100,7 @@ type ConfigInfo struct { StatsOneLine bool StatsOneLineDate bool // If we want a date prefix at all StatsOneLineDateFormat string // If we want to customize the prefix + ErrorOnNoTransfer bool // Set appropriate exit code if no files transferred Progress bool Cookie bool UseMmap bool diff --git a/fs/config/configflags/configflags.go b/fs/config/configflags/configflags.go index 890ac2c56..d142f42c6 100644 --- a/fs/config/configflags/configflags.go +++ b/fs/config/configflags/configflags.go @@ -101,6 +101,7 @@ func AddFlags(flagSet *pflag.FlagSet) { flags.BoolVarP(flagSet, &fs.Config.StatsOneLine, "stats-one-line", "", fs.Config.StatsOneLine, "Make the stats fit on one line.") flags.BoolVarP(flagSet, &fs.Config.StatsOneLineDate, "stats-one-line-date", "", fs.Config.StatsOneLineDate, "Enables --stats-one-line and add current date/time prefix.") flags.StringVarP(flagSet, &fs.Config.StatsOneLineDateFormat, "stats-one-line-date-format", "", fs.Config.StatsOneLineDateFormat, "Enables --stats-one-line-date and uses custom formatted date. Enclose date string in double quotes (\"). See https://golang.org/pkg/time/#Time.Format") + flags.BoolVarP(flagSet, &fs.Config.ErrorOnNoTransfer, "error-on-no-transfer", "", fs.Config.ErrorOnNoTransfer, "Sets exit code 9 if no files are transferred, useful in scripts") flags.BoolVarP(flagSet, &fs.Config.Progress, "progress", "P", fs.Config.Progress, "Show progress during transfer.") flags.BoolVarP(flagSet, &fs.Config.Cookie, "use-cookies", "", fs.Config.Cookie, "Enable session cookiejar.") flags.BoolVarP(flagSet, &fs.Config.UseMmap, "use-mmap", "", fs.Config.UseMmap, "Use mmap allocator (see docs).")