logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/
commit: c7250c2e64a8bccab55915514887d9a7ccc0ee5b
parent b8e206e0122b76df02aa9fc980d160361b66ab35
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 28 Dec 2025 09:24:42 +0100

cmd/mv: add -I option

Diffstat:

Mcmd/mv.139++++++++++++++++++++-------------------
Mcmd/mv.c25++++++++++++++++++++-----
2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/cmd/mv.1 b/cmd/mv.1 @@ -1,7 +1,7 @@ .\" utils-std: Collection of commonly available Unix tools .\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> .\" SPDX-License-Identifier: MPL-2.0 -.Dd November 10, 2024 +.Dd December 28, 2025 .Dt MV 1 .Os .Sh NAME @@ -9,17 +9,17 @@ .Nd move and rename files .Sh SYNOPSIS .Nm -.Op Fl f Ns | Ns Fl i Ns | Ns Fl n +.Op Fl f Ns | Ns Fl Ii Ns | Ns Fl n .Op Fl Tv .Ar source .Ar destfile .Nm -.Op Fl f Ns | Ns Fl i Ns | Ns Fl n +.Op Fl f Ns | Ns Fl Ii Ns | Ns Fl n .Op Fl v .Ar source... .Ar destdir .Nm -.Op Fl f Ns | Ns Fl i Ns | Ns Fl n +.Op Fl f Ns | Ns Fl Ii Ns | Ns Fl n .Op Fl v .Fl t Ar destdir .Ar source... @@ -52,27 +52,16 @@ to create the full destination path. .Bl -tag -width _f .It Fl f Force, do not ask before overwriting to the destination path. -Overrides previously set -.Fl i -and -.Fl n -options. +.It Fl I +Prompt for confirmation before moving a file, +implies +.Fl i . .It Fl i Interactive, causes .Nm to ask before overwriting a file. -Overrides previously set -.Fl f -and -.Fl n -options. .It Fl n No-clobber, never overwrite. -Overrides previously set -.Fl f -and -.Fl i -options. .It Fl t Ar destdir Set the destination directory. .It Fl T @@ -80,6 +69,14 @@ Always treat destination as a file. .It Fl v Verbose, write which action has been done. .El +.Pp +For the +.Fl f , +.Fl Ii , +and +.Fl n +options, the last one specified determines the behavior of +.Nm . .Sh EXIT STATUS .Ex -std .Sh STANDARDS @@ -89,6 +86,10 @@ IEEE Std 1003.1-2024 (“POSIX.1”) specification. .Pp The +.Fl I +option is an utils-std original extension. +.br +The .Fl n , .Fl t Ar destdir , .Fl T , diff --git a/cmd/mv.c b/cmd/mv.c @@ -43,6 +43,7 @@ const char *argv0 = "mv"; bool no_clob = false, force = false, interact = false, verbose = false; +bool always_interact = false; bool opt_T = false; static int stdin_tty = 0; @@ -265,6 +266,17 @@ do_renameat(struct named_fd srcdir, } } } + else if(interact && always_interact) + { + if(!consentf("mv: Move file '%s%s%s' to '%s%s%s'? [yN] ", + srcdir.name, + srcdir.sep, + src, + destdir.name, + destdir.sep, + dest)) + return 0; + } if(renameat(srcdir.fd, src, destdir.fd, dest) < 0) { @@ -408,9 +420,9 @@ do_renameat(struct named_fd srcdir, static void usage(void) { - fprintf(stderr, "Usage: mv [-f|-i|-n] [-Tv] source dest\n"); - fprintf(stderr, " mv [-f|-i|-n] [-v] source... destdir\n"); - fprintf(stderr, " mv [-f|-i|-n] [-v] -t destdir source...\n"); + fprintf(stderr, "Usage: mv [-f|-Ii|-n] [-Tv] source dest\n"); + fprintf(stderr, " mv [-f|-Ii|-n] [-v] source... destdir\n"); + fprintf(stderr, " mv [-f|-Ii|-n] [-v] -t destdir source...\n"); } int @@ -432,6 +444,7 @@ main(int argc, char *argv[]) // clang-format off static struct option opts[] = { {"force", no_argument, NULL, 'f'}, + {"always-interactive", no_argument, NULL, 'I'}, {"interactive", no_argument, NULL, 'i'}, {"no-clobber", no_argument, NULL, 'n'}, {"target-directory", required_argument, NULL, 't'}, @@ -442,9 +455,9 @@ main(int argc, char *argv[]) // clang-format on // Need + as first character to get POSIX-style option parsing - for(int c = -1; (c = getopt_long(argc, argv, "+:fint:Tv", opts, NULL)) != -1;) + for(int c = -1; (c = getopt_long(argc, argv, "+:fIint:Tv", opts, NULL)) != -1;) #else - for(int c = -1; (c = getopt_nolong(argc, argv, ":fint:Tv")) != -1;) + for(int c = -1; (c = getopt_nolong(argc, argv, ":fIint:Tv")) != -1;) #endif { switch(c) @@ -454,7 +467,9 @@ main(int argc, char *argv[]) interact = false; no_clob = false; break; + case 'I': case 'i': + if(c == 'I') always_interact = true; force = false; interact = true; no_clob = false;