Linux: How to eval the contents of STDOUT?

4

Consider you have a file with some sort of terminal command. How might each line be executed? Can you pipe the output of more into an eval?

%> more ./foo.txt

Edit:

After some help/guidance from the comments, I think I should also make note that it's been a while since I've done any shell scripting, so while I say eval I may mean echo or some other way of executing code.

If foo.txt contains various lines of code, but I want to execute the line that contains echo 'bar bar', I'm looking for a way to do that from, let's say a grep. Something logically similar to:

grep echo foo.txt | xargs echo

vol7ron

Posted 2013-04-15T14:21:49.957

Reputation: 403

Answers

5

If you just need to evaluate every line of a file, you don't need a complicated eval or stdout redirection. Two easy options:

  • Source the file (source filename.sh or . filename.sh).
  • Make the file executable and run it (chmod +x filename.sh; ./filename.sh)

If you really need to eval each line of a file in a loop, do it with while:

while IFS= read -r line; do eval "$line"; done < filename.sh

You can also pipe the output of any command to while:

grep foo filename.sh | while IFS= read -r line; do eval "$line"; done

If you need to pass something to source (or .), which expects a file name as an argument, you can use process substitution:

source <( grep foo filename.sh )

slhck

Posted 2013-04-15T14:21:49.957

Reputation: 182 472

I like, but is there a way to do this w/o using bash? I know I tagged it, so I'm just curious, since I don't always use it. – vol7ron – 2013-04-15T14:38:59.520

source isn't Bash-specific and should work in most other shells (Bourne Shell, (t)csh) as well. – slhck – 2013-04-15T14:48:02.810

Right now, source would work but I like to think ahead in the case that there are lines I wan't to strip out and possibly use the output of grep – vol7ron – 2013-04-15T14:59:27.863

2Technically, source is a non-standard synonym for .. – chepner – 2013-04-15T15:08:18.280

@chepner: right, but can you pump more/grep into an eval (guessing echo) from the terminal command line? Perhaps into find -exec? – vol7ron – 2013-04-15T17:27:20.757

@vol7ron: You cannot pipe into eval, since it does not read from standard input. It takes a string as an argument. That said, why do you think you need to use eval? It's rarely necessary. – chepner – 2013-04-15T17:29:35.537

@chepner not saying I do - been a while since I've done any shell scripting. I may need to edit the question, instead of posting this as a comment, but I'm looking to execute specific lines from a file (eg output of grep string_match foo.txt) I figured I'd have to pipe that into echo or eval – vol7ron – 2013-04-15T17:36:12.547

@vol7ron You can use process substitution to pass the output of a list of commands to source, or pipe the output from your scripts to while. – slhck – 2013-04-15T17:42:29.270

@slhck don't get me wrong the while worked in Bash, I was looking for something that may be shell independent, which again, I asked too open of a question so it's entirely my fault. The source I think would work, just isn't as descriptive when I go back to read what I did a couple years from now :) – vol7ron – 2013-04-15T17:45:31.480

@vol7ron while for reading each line and process substitution is also supported in Zsh and ksh. You can use while in the Bourne Shell as well, so this is as portable as you can get AFAIK. (t)csh uses completely different syntax, so you won't get far with that I'm afraid. – slhck – 2013-04-15T17:53:42.590

@slhck and that's the rub :( – vol7ron – 2013-04-15T17:54:48.490

@vol7ron Not pretty, but you can always use a temporary file and source that of course. – slhck – 2013-04-15T18:32:23.587

@slhck thanks for continuing to think on this, I'd rather force the use of bash than to go that route, but it's an interesting idea. – vol7ron – 2013-04-15T18:40:34.713