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?
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.-maxdepth 1
include only the current directory.-not -name ".*"
exlude hidden directories.-type d
include only directories, not files.find -print0
used withxargs -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.Two options:
or
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.In this specific case, you could also use
find
: