2

TL/DR: I'm working in Solaris 10. I have a ls ... | egrep ... command, and I need to know if it outputs any results or not. I could just add a | wc -c to the end; but I need the result (0 or non-zero) to be in the exit code, not in the output. And I can't use if, it's not a bash script, I can only execute a single command.


Long version: I'm writing a maintenance process to compress and remove old log files in a Solaris 10 system. It checks all the .log or .xml files inside a given path, takes the ones which were last modified on a given month, creates a .tar with them, and then removes the original files:

ls -Egopqt /path/ | egrep -i '2016-10-[0123][0-9] .*(\.log$|\.xml$)' | awk '{ print $7 }'
| xargs tar -cvf target.tar

And the same to remove the files, just replacing the last part with: | xargs -i rm {}

I'm probably overcomplicating it, but it works. Unless there are no files for a given month; if that's the case, I get an error saying tar: Missing filenames. How can I check it before attempting to create the tar? I thought of something like this, using wc to check if there is an output or not:

ls ... | egrep ... | wc -c

Which correctly outputs 0 when there aren't any files, and another number otherwise. The problem is: I can't see the output, only the exit code (which is always 0 since there is no error). I'm not doing this in a bash script, I'm working with Siebel CRM: I have a javascript function which generates the commands and executes them with Clib.system calls. The only thing I can see is the exit code: 0 for OK, non-zero for an error (I see the actual number, not "non-zero").

Previously I had a similar requeriment, to check if a single file exists or not, and this answer helped me to get to this:

[ -f filename ] && exit 111 || exit 0

I'm successfully getting either 111 or 0, depending on if filename exists or not. But I can't get it to work with the ls ... | egrep ... | wc command. I've tried using this syntax:

[[ $( ls -Egopq /path/ | egrep -i ... | wc -c ) -ne 0 ]] && exit 111 || exit 0

But I'm getting always exit code 2, it doesn't matter if there are files or not. What am I doing wrong?


PS: I know I could write a tiny shell script to perform the checks, use a simple if to compare the output, and then return whatever exit code I want. Also, I actually can access a command's output, I'd just need to redirect it to a > tempfile and then read it from Siebel. However, I'd prefer to avoid both of these options, as I'm trying to avoid creating unnecessary (temp or permanent) files.

6

egrep returns non-zero if no lines were matched.

  • Unbelieveable... I've been trying commands for a few hours, and I didn't think of that!? – AJPerez Nov 22 '16 at 17:34
  • I seem to remember having the same feeling when I first discovered this feature myself :D – Muzer Nov 22 '16 at 17:35
  • Ah yes that is another alternative, just add set -o pipefail;....;set +o pipefail. – Valentin B. Nov 22 '16 at 17:35
1

From xargs manual:

--no-run-if-empty
-r     If  the standard input does not contain any nonblanks, do not run the command.  
       Normally, the command is run once even if there is no input.  This option is a GNU extension.

Seems like doing ... | xargs -r tar -cvf target.tar should do the trick !

  • Thanks! However, my Solaris xargs version doesn't have that option. Anyway, I also need to know if there were files or not, in order to stop further actions, not only to avoid the tar creation – AJPerez Nov 22 '16 at 17:38
  • Ok, I will leave this here for the sake of completeness, but in your case Muzer's solution should work! – Valentin B. Nov 22 '16 at 17:39

Your Answer

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

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