Added a --dry-run and -d option for not making changes when running the rename command. Also made changes to the man page. Having a dry-run option is useful when running a scary rename. -- Sincerely, Alexander F Rødseth / xyproto
From d75d6b1ce3819bdd99e2d84a79f7d642f021cd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=20R=C3=B8dseth?= <xyproto@xxxxxxxxxxxxx> Date: Mon, 13 Feb 2017 13:44:38 +0100 Subject: [PATCH] rename: add --dry-run option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexander F Rødseth <xyproto@xxxxxxxxxxxxx> --- misc-utils/rename.1 | 13 ++++++++----- misc-utils/rename.c | 28 +++++++++++++++++----------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/misc-utils/rename.1 b/misc-utils/rename.1 index 165d61eff..4023fd5f9 100644 --- a/misc-utils/rename.1 +++ b/misc-utils/rename.1 @@ -22,6 +22,9 @@ Do not rename a symlink but its target. .BR \-v , " \-\-verbose" Show which files where renamed, if any. .TP +.BR \-d , " \-\-dry-run" +Do not make any changes. +.TP .BR \-V , " \-\-version" Display version information and exit. .TP @@ -60,11 +63,11 @@ rename '_with_long_name' '' file_with_long_name.* .RE will remove the substring in the filenames. .SH WARNING -The renaming has no safeguards. If the user has permission to rewrite file names, -the command will perform the action without any questions. For example, the -result can be quite drastic when the command is run as root in the /lib -directory. Always make a backup before running the command, unless you truly -know what you are doing. +The renaming has no safeguards except the dry-run option. If the user has +permission to rewrite file names, the command will perform the action without +any questions. For example, the result can be quite drastic when the command +is run as root in the /lib directory. Always make a backup before running the +command, unless you truly know what you are doing. .SH "EXIT STATUS" .RS .PD 0 diff --git a/misc-utils/rename.c b/misc-utils/rename.c index f53b236e2..d04a9a284 100644 --- a/misc-utils/rename.c +++ b/misc-utils/rename.c @@ -53,7 +53,7 @@ static int string_replace(char *from, char *to, char *s, char *orig, char **newn return 0; } -static int do_symlink(char *from, char *to, char *s, int verbose) +static int do_symlink(char *from, char *to, char *s, int verbose, int dry_run) { char *newname = NULL, *target = NULL; int ret = 1; @@ -76,21 +76,21 @@ static int do_symlink(char *from, char *to, char *s, int verbose) target[sb.st_size] = '\0'; if (string_replace(from, to, target, target, &newname)) ret = 0; - else if (0 > unlink(s)) { + else if (!dry_run && 0 > unlink(s)) { warn(_("%s: unlink failed"), s); ret = 2; - } else if (symlink(newname, s) != 0) { + } else if (!dry_run && symlink(newname, s) != 0) { warn(_("%s: symlinking to %s failed"), s, newname); ret = 2; } - if (verbose && ret == 1) + if (verbose && (dry_run || ret == 1)) printf("%s: `%s' -> `%s'\n", s, target, newname); free(newname); free(target); return ret; } -static int do_file(char *from, char *to, char *s, int verbose) +static int do_file(char *from, char *to, char *s, int verbose, int dry_run) { char *newname = NULL, *file=NULL; int ret = 1; @@ -101,11 +101,11 @@ static int do_file(char *from, char *to, char *s, int verbose) file = s; if (string_replace(from, to, file, s, &newname)) return 0; - else if (rename(s, newname) != 0) { + else if (!dry_run && rename(s, newname) != 0) { warn(_("%s: rename to %s failed"), s, newname); ret = 2; } - if (verbose && ret == 1) + if (verbose && (dry_run || ret == 1)) printf("`%s' -> `%s'\n", s, newname); free(newname); return ret; @@ -124,6 +124,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out) fputs(USAGE_OPTIONS, out); fputs(_(" -v, --verbose explain what is being done\n"), out); fputs(_(" -s, --symlink act on the target of symlinks\n"), out); + fputs(_(" -d, --dry-run do not make any changes\n"), out); fputs(USAGE_SEPARATOR, out); fputs(USAGE_HELP, out); fputs(USAGE_VERSION, out); @@ -134,13 +135,14 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out) int main(int argc, char **argv) { char *from, *to; - int i, c, ret = 0, verbose = 0; - int (*do_rename)(char *from, char *to, char *s, int verbose) = do_file; + int i, c, ret = 0, verbose = 0, dry_run = 0; + int (*do_rename)(char *from, char *to, char *s, int verbose, int dry_run) = do_file; static const struct option longopts[] = { {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, + {"dry-run", no_argument, NULL, 'd'}, {"symlink", no_argument, NULL, 's'}, {NULL, 0, NULL, 0} }; @@ -150,11 +152,14 @@ int main(int argc, char **argv) textdomain(PACKAGE); atexit(close_stdout); - while ((c = getopt_long(argc, argv, "vsVh", longopts, NULL)) != -1) + while ((c = getopt_long(argc, argv, "vsVhd", longopts, NULL)) != -1) switch (c) { case 'v': verbose = 1; break; + case 'd': + dry_run = 1; + break; case 's': do_rename = do_symlink; break; @@ -163,6 +168,7 @@ int main(int argc, char **argv) return EXIT_SUCCESS; case 'h': usage(stdout); + // fallthrough default: errtryhelp(EXIT_FAILURE); } @@ -179,7 +185,7 @@ int main(int argc, char **argv) to = argv[1]; for (i = 2; i < argc; i++) - ret |= do_rename(from, to, argv[i], verbose); + ret |= do_rename(from, to, argv[i], verbose, dry_run); switch (ret) { case 0: -- 2.11.1