Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am trying to understand how to use the stdout as the stdin of another command. To test it, I am trying to use the following command to delete all directories from the current folder.

ls -d -- */ | rm -rf $1

I would expect the result of ls -d -- */ to be piped into the input of the rm, but it does not work. Ideas?

share|improve this question
    
use xargs to convert stdout to args. why dont you do rm -rf * which does the same thing in the shown example? –  balki Aug 6 '12 at 14:39
    
nope. it will only work with $1 –  Pomario Aug 6 '12 at 15:11
2  
Never parse the output of ls. It's impossible to do it reliably and there's always a better alternative. In this case, refer to find. –  Scott Severance Aug 6 '12 at 21:35

4 Answers 4

up vote 3 down vote accepted

Not all commands/programs will directly accept piped input (including rm). Additionally, why are you using the bash substitution variable $1 outside of a script?

For your general case, you need to look at xargs, a utility whose goal is to simplify such scenarios by taking a list from stdin and then invoking a command with the elements of that list (in different possible ways).

For what you want to do...(use it wisely!): rm -rf * (or .) will suffice.

share|improve this answer
3  
rm -rf will also delete things in the current folder that are not directories! –  Eliah Kagan Aug 6 '12 at 19:01
    
agreed with Eliah.. it does not solve the original question, so -1 –  SpamapS Aug 8 '12 at 19:05
find -maxdepth 1 -not -name ".*" -type d -print0 | xargs -n1 -0 rm -rf

-maxdepth 1 include only the current directory. -not -name ".*" exlude hidden directories. -type d include only directories, not files. find -print0 used with xargs -0 will use files and directories that have names with weird characters. xargs -n1 perform the command (in this case rm) one line at a time.

share|improve this answer

Two options:

ls -d -- */ | xargs rm -r

or

rm -r `ls -d -- */`

In the past, xargs was necessary because there was a limit on command line argument lists. xargs will put a reasonable number on each execution and run the given command multiple times (it also has some cool stuff to help you do concurrent execution). However, in recent kernels, this limitation is gone, so the simpler rm command with no pipe will work fine, though it will use up more RAM so if there are many many thousands of arguments xargs will still be more efficient.

Its worth noting that you do not need -f for rm, as that is only needed when you want rm to continue when a file does not exist, or to skip any interactive confirmations. Since you have ls telling you they exist, its safer to leave it off, and then the usual -i alias will save you from accidentally deleting write-protected files and directories.

share|improve this answer
3  
It's worth saying here: Never try to parse the output of ls. It's a recipe for trouble. –  Scott Severance Aug 6 '12 at 21:29

In this specific case, you could also use find:

find . -maxdepth 1 -type -d -exec rm -rf {} \;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.