1

Say I have a list.txt of files I want to check.

cat list.txt

and for each file, I want to perform an action

cat list.txt | xargs -I {} touch {}

But depending on the outcome of the action, I want to react accordingly:

cat list.txt | xargs -I {} touch {} | if [-z - ]; then echo "blank file"; fi;

This doesn't work properly, and I'm not sure why not... So, How can I properly test the value of stdout -?- - and, as a bonus- how could I pass the contents of {} to the final portion? To the effect of:

cat list.txt | xargs -I {} touch {} | if [-z - ]; then echo "{} is a blank file"; fi;

Perhaps this should be a complete bash script, but I would prefer if I could learn to do this in one line, since the applications for this could be useful in many ways --

Here is a more practical example:

time john -incremental -stdout | grep 'clientsWeakPassword' | if [ ! -z - ]; then exit 0;

So, this script would randomly generate passwords, and stop when it hits the password specified, displaying the amount of time it took to 'crack' that password...

And ideally, it would also output something like "'clientsWeakPassword' took Xminutes to crack using random guessing" --

But, this chain could also be used to check for a certain thing in log files, etc, etc, etc -

At any rate, I hope someone can point me in the right direction.

Many thanks -

7
  • 1
    Just a passing remark: as someone who learned computing when 64KB was a lot of memory, I have always abhorred inefficiency. There is nothing functionally wrong with cat list.txt | xargs ..., but it requires one or more file accesses to find cat, another to open a pipe, then possibly swapping out a group of pages to free memory for cat, reading through the entire file to copy it into memory for execution, and the overheads of closing the process and pipe afterwards, and eventually swapping back into memory the pages that cat displaced.
    – AFH
    Oct 13, 2014 at 21:02
  • 1
    All that is required is the single file open, read and close for xargs <list.txt ....
    – AFH
    Oct 13, 2014 at 21:02
  • very good to know... I've always used bash as a tool, not a scripting language, and I'm only recently getting into doing more advanced things like this, so this is precisely the sort of direction & instruction I was looking for - so that remark is a bonus tip for me - and I am grateful ^_^
    – rm-vanda
    Oct 13, 2014 at 22:05
  • 1
    Thanks for listening. I should add that there could be unusual circumstances when you might want cat list.txt | ..., in order to isolate the recipient program from your input file. And I take your point that if you are doing a one-off command, efficiency doesn't matter (though in my case, the amount of typing does!).
    – AFH
    Oct 13, 2014 at 23:48
  • Thank you for instructing -! For some reason, I never absorb using the caret in that direction -- I always think of it as cat something > some_file -- so, it is quite helpful to know -- that is a habit I should break if I wish to improve in bash - so Thank you -!
    – rm-vanda
    Oct 14, 2014 at 0:09

1 Answer 1

2

If you want to do more than one thing, spawn a shell:

xargs -t sh -c '
    for f; do
        touch "$f"
        [ -s "$f" ] || echo "$f is zero size or does not exist" 
    done
' - < list.txt

But by this point, you might as well use a while read loop instead of xargs.

3
  • Great, thank you, that's exactly the sort of thing I'm looking for - I've never used while read before, so that's exactly what I need to know... However, my example was theoretical, and what I really need is to have the stdout in the if statement... (touch was obviously a bad choice, since there is no stdout...)
    – rm-vanda
    Oct 13, 2014 at 19:37
  • if itself doesn't do anything with stdout. The command following if might. I think you need to make your question much more explicit about what you're actually trying to do. Oct 13, 2014 at 23:38
  • Well, I think there may be many applications for passing stdout to an if statement, but what originally got me rolling on this was essentially a Proof of Concept on how easy it is to crack WordPress passwords... If you can show a client it only takes one line and time to crack a password, then they listen. Unfortunately, I've bluffed about the 'one-line' part, but since it is 2/3rds there, I thought surely there was an easy solution for the last third that I simply wasnt aware of... But, you certainly gave me the right direction, and I will very likely accept your answer. Many thanks.
    – rm-vanda
    Oct 14, 2014 at 0:00

You must log in to answer this question.

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