I'm trying to run a server that writes to $log (a txt file) and then find all the text in the logfile that starts with '[1]' and put it in another file. Here's my attempt. tee -a $log works along with everything else. The grep command doesn't though.

run="tail -n0 -f -s 0.01 $cmds | (while true; do $tron --userconfigdir $userconfigdir --userdatadir $userdatadir --vardir $var; done) | tee -a $log | grep '^[1]' > ${var}logs/chatlogs.log"

What can be done to copy all the text from tee -a $log starting with '[1]' to another file?

  • 1
    Sorry, but why do you have it like run="..."? because you want to then do $run ? if so, then you almost certainly need to do eval $run, and then, you are opening up a whole new can of worms. Leave out the assingment stuff and just run as is, is my recommendation. Also use shell debug option set -vx to see how/when vars, etc. are being evaluated. good luck. – shellter Jul 31 '11 at 14:16
  • @KevinDuke: I removed your note about escaping brackets not working, that should be a comment under an answer, not an edit. – Caleb Aug 1 '11 at 11:18
  • @shellter: Why don't you make that an answer, I think it's almost certainly the explanation as to why even escaping the brackets failed him. – Caleb Aug 1 '11 at 11:21
  • @Caleb: Thanks, just seeing this, I don't get here to Unix/Linux very often. At this point, seems OP has lost interest ;-( – shellter Aug 9 '11 at 15:35
  • @shellter: Don't worry about OP's loosing interest. They may or may not be around but it is always useful to have a properly documented and explained question/answer pair. That's what puts SE in a league of it's own in the QnA world. Also the OP has been back to check since the last things posted that would have pinged him. He's most active on SO but still get's pinged across sites and comes back here to look when something changes on this question. – Caleb Aug 9 '11 at 16:43

Don't put commands in strings. The way to define compound commands is functions.

Then remember the most important rule of shell programming: always put double quotes around variable substitutions, e.g. "$foo".

You have the following code (relying on the variables cmds, log, tron, userconfigdir, userdatadir and var):

run () {
  tail -n0 -f -s 0.01 "$cmds" |
  while true; do
    "$tron" --userconfigdir "$userconfigdir" --userdatadir "$userdatadir" --vardir "$var"
  done |
  tee -a "$log" |
  grep '^[1]' > "${var}logs/chatlogs.log"

Now that the code is in a readable form, you can see that $tron is being executed in an endless loop. I don't know what you actually want to do, but you do need to put a termination condition in that loop.

| improve this answer | |

[...] are operators for character lists. You probably want to do grep '^\[1\]'.

| improve this answer | |
  • This answer is correct in so far as it fixes the grep, but it still fails in the OP's case because he is running eval on the whole command string, which means these brackets would need to be DOUBLE escaped. The real right answer is going to involve helping him to avoid eval as well as properly escape these operators. – Caleb Aug 1 '11 at 11:21

I think it should be enough if you escape the square brackets: grep '^\[1\]'

| improve this answer | |

First of all, use shell debug option set -vx to see how/when vars, etc. are being evaluated.

Sorry, but why do you have your code setup like


because going to later use the variable $run ?

If so, then you almost certainly need to do

eval "$run"

which is opening up a whole new can of worms as far as escaping special characters. As another commentor points out you'll not just have to escape the required characters, you'll have to doubly escape them. When I used to get things like this to work, I could wind up with escapes like \\\\\ (5!) to get things working.

Without further explanation of the context for this code, my recommendation is to leave out the run= stuff and just run tail -n0 -f -s 0.01 $cmds |.... as is.

Also, per Gilles comment, and to amplify on it, your whole pipe-line doesn't make much sense,

 tail -n0 -f -s 0.01 $cmds | (while true; do $tron ....

A. we don't know what is in $cmds

B. There is nothing I can see inside the sub-shell (while true; ...) that is reading the output of the tail cmd. If you say it is passed complete into the subsequent tee after end of the while , then I've learned something new.

C. Do you really want to execute $tron command as fast as you can in an infinite loop? On a lot of systems, this will wind up consuming at least 1 CPUs full capacity. Maybe add a sleep 1?

Adding more context about what you're trying to accomplish will help us help you! Good luck.

| improve this answer | |

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.