LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 04-01-2013, 03:20 AM   #1
Seb-o-tronic
LQ Newbie
 
Registered: Dec 2012
Posts: 10

Rep: Reputation: Disabled
Command line : xargs and rm


Hello,

I'm currently studying Linux reading "Linux essentials" available on LPIC website.

On page 90, a comparison of "find ... -exec rm -i ..." and "find ... | xargs rm -i" is made.

I've just tried these two commands in order to understand how they works. The first one (using "-exec") seems to perfectly work, the second one does not.

As shown below, the rm command's "-i" option ask for a confirmation but I can not give an answer. The prompt reapears instead a way to give my deletion agreement.

Code:
[sebastien@louise LinuxEssentials]$ ll
total 4
-rwx------. 1 sebastien sebastien 12 Apr  1 11:15 myscript
Code:
[sebastien@louise LinuxEssentials]$ find . -amin -10  | xargs -r rm -i '{}'
rm: cannot remove `{}': No such file or directory
rm: cannot remove `.': Is a directory
rm: remove regular file `./myscript'? [sebastien@louise LinuxEssentials]$
Please, could you help me to understand what occures?

I'm not (yet?) a Linux professionnal. I'm an electronician who's interested in embedded Linux ... so, I have to learn!

I thank you so mutch in advance for your help.

Last edited by Seb-o-tronic; 04-01-2013 at 04:18 AM.
 
Old 04-01-2013, 04:03 AM   #2
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
If you remove the "-i" from these commands they both attempt non-interactive removal of files.

The one using -exec attempts one rm command per file to remove. The one with xargs writes a list of filenames to xargs where the xargs command puts as many of these text strings as possible into the arguments of an rm command (before doing 2nd and later commands if the input is large enough).

I suggest avoiding the xargs version as the files removed by rm are the result of text processing by xargs and may not be the original filenames as seen by find. For instance if root runs this in a cron job:
Code:
find /tmp -type f -name \*.mp3 -mtime +30 | xargs rm
The above can be manipulated by a malicious user intending to get /etc/passwd supplied as an argument to rm.
Code:
cd /tmp
mkdir  -p "problem /etc/passwd /stuff"
touch -t 197001011159 "problem /etc/passwd /stuff"/remove_me.mp3

Last edited by linosaurusroot; 04-01-2013 at 04:05 AM.
 
Old 04-01-2013, 04:19 AM   #3
Seb-o-tronic
LQ Newbie
 
Registered: Dec 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by linosaurusroot View Post
If you remove the "-i" from these commands they both attempt non-interactive removal of files.
Sorry I forgot to paste my terminal screen - I've just edited my previous message.

What's appening is that "-i" ask for a confirmation but I cannot answer.

Last edited by Seb-o-tronic; 04-01-2013 at 04:24 AM.
 
Old 04-01-2013, 07:39 AM   #4
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
There are two oversights -

1) the -i invokes the interactive removal, so you have to confirm that you want to remove the file.
Fixing this is easy - just take the -i option off.

2) the {} sequence is the internal identification used by find for the file name.
Since you are using xargs (which reads its parameter from stdin or the pipe) you don't use it on the rm command - xargs will put it there.
 
Old 04-01-2013, 08:24 AM   #5
Seb-o-tronic
LQ Newbie
 
Registered: Dec 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
Sorry, English is a foreign language for me, I guess we don't understand :
- I understand how the command works. But it seems to not work as it should.
- I want to use interactive mode
- BUT (!) If the command above ask me to confirm deletion (as it should do, and does), it does not wait for my answer.

Thus, I understand how it should work but I don't understand why it does not wait for my answer.

Code:
rm: remove regular file `./myscript'?
--> I can not say "yes" or "no" : the prompt appear without waiting.

Code:
rm: remove regular file `./myscript'? [sebastien@louise LinuxEssentials]$
 
Old 04-01-2013, 09:08 AM   #6
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
That is because rm can't access stdin - it is coming from the find. If only one file is there, the script terminates as stdin is closed. If there are two files, the second file name is used to answer the prompt... and if it isn't "yes", then again it exits. If you have many files, then you should see the prompt for every other file... and unless one of the odd numbered files is "yes", nothing will be done.
 
Old 04-01-2013, 10:10 AM   #7
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Replace "-exec" with "-ok" to get interactive behaviour.
 
Old 04-02-2013, 10:35 AM   #8
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Rep: Reputation: 17
The proper syntax for the below command

find . -amin -10 | xargs -r rm -i '{}'

is

find . -amin -10 | xargs -I {} rm -i {}
 
Old 04-02-2013, 03:47 PM   #9
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Quote:
Originally Posted by edwardcode View Post
The proper syntax for the below command

find . -amin -10 | xargs -r rm -i '{}'

is

find . -amin -10 | xargs -I {} rm -i {}
Not with a pipe. the '{}' is only understood by the find process. What you get is "... xargs -I {} rm -i {}" and the error (well usually) "file not found".
 
Old 04-02-2013, 03:59 PM   #10
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,783

Rep: Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214
Quote:
Originally Posted by jpollard View Post
Not with a pipe. the '{}' is only understood by the find process. What you get is "... xargs -I {} rm -i {}" and the error (well usually) "file not found".
Sorry, but the xargs command does allow you to define a string that will be replaced with an argument read from stdin, and "{}" is as good a string as any other.
 
Old 04-02-2013, 04:11 PM   #11
whizje
Member
 
Registered: Sep 2008
Location: The Netherlands
Distribution: Slackware64 current
Posts: 594

Rep: Reputation: 141Reputation: 141
Code:
bash-4.2$ ls tmp
test1.mp3  test2.mp3  test3.mp3
bash-4.2$ find tmp -maxdepth 1 -name '*.mp3' -maxdepth 1 | xargs -n1 -p rm
rm tmp/test3.mp3 ?...y
rm tmp/test2.mp3 ?...n
rm tmp/test1.mp3 ?...y
bash-4.2$ ls tmp
test2.mp3
-n1 passes one argument at the time
-p interactive mode
 
Old 04-02-2013, 10:32 PM   #12
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by jpollard View Post
Not with a pipe. the '{}' is only understood by the find process. What you get is "... xargs -I {} rm -i {}" and the error (well usually) "file not found".
The "-I {}" used with xargs prepares for the {} later in the command (although it's pointless in this case where all the filenames come at the end).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
xargs: unmatched single quote; by default quotes are special to xargs unless you use Raakh5 Linux - Newbie 7 05-21-2014 07:26 PM
[SOLVED] basename with command substitions and xargs dugan Programming 3 06-21-2011 09:58 AM
clarification on find + xargs rm command dtra Linux - General 2 05-17-2006 05:56 AM
Help me to understand this command: find...| grep -e ... | xargs rm -f ROBERT483599 Red Hat 2 02-14-2006 08:21 AM
PHP: what's wrong with this line (shell_exec, find, xargs, grep)? J_Szucs Programming 3 11-19-2003 07:44 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 01:26 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration