0

I would like to search for all the nohup.out in my mounted filesystems, and delete them.

  1. There are some directories and files whose filenames contain space, so I think of xargs -0.

  2. To be safe, I would like to interactively delete them, i.e. be asked if I really want to delete them. So I think of rm -i and xargs -p

  3. I also would like to delete each found file seperately, so I think of xargs -n 1.

But the following command doesn't work in the way I hope.

locate  -i nohup.out | xargs -0 -n 1 -p rm -i

It doesn't prompt each file to be removed and ask for my permission.

I wonder why and what command works as I hope?

By the way my xargs version is xargs (GNU findutils) 4.4.2. Can it be the reason?

6
  • locate is only as good as the db it looks up. If you haven't run updatedb in a while, locate will be near useless. You'll want to use find. Additionally, you don't specify what doesn't work the way you hope?
    – ffledgling
    Feb 28, 2016 at 0:06
  • 1
    yes, I want to use locate after updatedb, because it is faster. My command doesn't prompt each file to be removed and ask for my permission
    – Tim
    Feb 28, 2016 at 0:07
  • what's the output look like for you when you run it? I run xargs without passing the -i to rm and it works just fine.
    – ffledgling
    Feb 28, 2016 at 0:12
  • 1
    AFAIK locate doesn't produce null-separated output by default, so you're creating a newline-separated list which xargs -0 will treat as a single argument, no? Feb 28, 2016 at 0:23
  • @steeldriver: you may be right.
    – Tim
    Feb 28, 2016 at 0:28

4 Answers 4

4

Use find not locate

find . -name "nohup.out" | xargs -n 1 -p rm

When you add rm -i it acts as the input for the -p prompt

You can use find this way too

find . -name "nohup.out" -exec rm -i {} \;
4
  • Thanks. what if use locate instead of find?
    – Tim
    Feb 28, 2016 at 0:09
  • I've never preferred locate for the fact that I have to updatedb
    – Marware
    Feb 28, 2016 at 0:24
  • Why is updatedb a reason?
    – Tim
    Feb 28, 2016 at 0:27
  • Mostly searching for files not necessarily using only its name, I've security concerns for locate addressed here unix.stackexchange.com/a/60208/49374
    – Marware
    Feb 28, 2016 at 0:42
2

But the following command doesn't work in the way I hope.

locate -i nohup.out | xargs -0 -n 1 -p rm -i

Of course if you are using xargs -0 then you must match that with locate -0.

It doesn't prompt each file to be removed and ask for my permission. I wonder why

xargs should read input from /dev/tty when prompting you. It works that way so that there is no conflict between the use of xargs's stdin for reading arguments from locate and reading responses for the -p option.

However, you are using xargs to run rm -i. The rm -i command also wants to read your input, which it will read from stdin. Hence it eats up part of xargs's input and things don't work how you expect.

and what command works as I hope?

If you are using Bash, this is one option:

xargs -a <(locate -0 -i nohup.out) -0 -n 1 -p rm -i

However, you can also do everything in find:

find / -depth -name nohup.out -ok rm -i '{}' ';'

Change ';' to '+' to delete more than one file at a time. This requirement and the various ways you can solve this problem are explained in the Texinfo manual for findutils.

4
  • Thanks. Is -depth here necessary?
    – Tim
    Jun 6, 2018 at 20:45
  • Strictly, no. But when removing things, you need to remove containing directories after their contents (else the removing fails). This means that in general using -depth is best. Since here we are using "rm" without "-r" we would not be able to remove a directory anyway. Jun 7, 2018 at 13:34
  • Thanks. I don't observe the problem that rm -i "eats up part of xargs's input and things don't work how you expect."
    – Tim
    Jun 8, 2018 at 3:48
  • You're right, I'd forgotten that I fixed this in git.savannah.gnu.org/cgit/findutils.git/commit/?id=6c40e5651 Jun 9, 2018 at 15:48
2

If you want interactive behaviour and prompting with xargs, you might want to do this instead:

locate  -i nohup.out | xargs -d '\n' -L1 -p rm
9
  • what if spaces in filenames?
    – Tim
    Feb 28, 2016 at 0:14
  • @Tim updated answer. see edit.
    – ffledgling
    Feb 28, 2016 at 0:20
  • Thanks. why use -L1? Why not -n 1?
    – Tim
    Feb 28, 2016 at 0:25
  • Can only one of xargs -p and rm -i be used, not both? When both, it seems answering yes doesn't commit a removal action.
    – Tim
    Feb 28, 2016 at 0:34
  • @Tim, I usually wouldn't expect an interactive command to run through another command that probably starts it as a subshell. Empirically, it tried it and it didn't work, so I'm going to assume both can't be used together, at least not in this way.
    – ffledgling
    Feb 28, 2016 at 0:39
1

POSIXly:

find /path/to/mounted_fs -xdev -type f -name nohup.out -exec rm -i {} +

-xdev limited find to search only in your mounted filesystems. Using -exec rm -i {} + like you use xargs but without issue with special characters in filename.


The problem with your command:

locate -i nohup.out | xargs -0 -n 1 -p rm -i

you told xargs to use \0 as input separator, but locate output did not use \0 but \n, so xargs would see locate output as a big string.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .