This is more of a challenge than anything: can it be done safely and elegantly in one line?

The main problem, both the patterns and the files are result of commands which may fail.

grep -Fxvf <(cmd-filter) <(cmd-list) | xargs -d "\n" gvfs-trash

  1. cmd-filter may return 0 to fail or output a bogus empty list if passed a bogus path (it's a knockoff remote ls).
  2. cmd-list is just a depth find. A failure here is not all bad, because even a typo just means the next, gvfs-trash program that will receive piped ouput, will not run on anything. It would be handy if a typo caused a failure though.

Obviously the main problem is the first. If it fails for any reason, or is empty because of a typo, all the files printed by cmd-list will be trashed. I'd like to avoid this, to say the least.

I've read on man that grep -f is supposed to fail grep if cmd-filter is empty, but i haven't experienced this in the above. If i replace cmd-filter by echo "" i get all the files in cmd-list. And what about failure from other reasons?

edit: thinking about this, this might because of the -v switch, which is necessary to invert the match to get the lines not in cmd-list. If so, i find it strange it finds the invert match of empty pattern list to be everything.

Anyway, since elegance may be impossible, and if there is no good response that is not 'just make a script you lazybones' i'd still mark correct a single line hack that uses tmp files or similar.

edit: I myself 'failed' this challenge and used a long script (ab)using vars and process substitution to make this. Turned out that i didn't need to check both error status and if the stdout was empty in cmd-filter too, because in all error cases i found it was empty too.

  • 1
    echo "" doesn't produce an empty file; it produces a file with a single line (which is empty). If you run true as cmd-filter you should get a different result. – Wumpus Q. Wumbley Jul 30 '17 at 0:05
  • Where did you read that "grep -f is supposed to fail grep if cmd-filter is empty"? At least for GNU grep, the manual seems pretty clear that "The empty file contains zero patterns, and therefore matches nothing." (hence grep -vf with an empty file argument matches everything). – steeldriver Jul 30 '17 at 0:06
  • ...and if your real cmd-filter is producing an empty line when you want it to produce an empty file, try cmd-filter | grep . – Wumpus Q. Wumbley Jul 30 '17 at 0:10
  • @i30817 what are you trying to achieve exactly? find can support filter and also can use exec to combine any command line you can use grep to find all files including your filters in it no need pass find to grep – αғsнιη Jul 30 '17 at 3:06
  • there doesn't seem to be any easy way for process substitution to send any kind of signal to grep. you could kill <signal> <grep's PID> in cmd-filter but even that's not going to be easy - grep is not the parent process (PPID) of <(cmd-filter), the shell that runs it is. i guess you could look for a grep process with the same PPID as cmd-filter itself but there might be more greps run in background by that shell (i.e. false-positives). IMO what you're trying to do is unsafe and you should use temporary files - that will at least allow you to abort easily if there's any problem. – cas Jul 30 '17 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.