jols
jols

Reputation: 549

Can I use ECHO to execute commands?

I've come up with a cool script that will produce the output that I need, but it only displays on the screen, so I have to copy, then paste in the commands to get them to execute. Here's the abbreviated version of my script:

#!/bin/bash
runc=/etc/csf/csf.pl -d
for IP in `tail -400 iptext.txt`
do
cc=`geoiplookup $IP`
echo -e $runc $IP    $cc | grep Algeria
echo -e $runc $IP    $cc | grep Argentina
echo -e $runc $IP    $cc | grep Armenia
echo -e $runc $IP    $cc | grep Azerbaijan
echo -e $runc $IP    $cc | grep Bolivia
echo -e $runc $IP    $cc | grep Brazil
done

Okay, so it loops through the list of IP addresses in iptext.txt, then does a geoIP lookup on each, if (in this example) there are two geoIP matches in the list, let's say for Armenia and Brazil, I will see output like this to the shell window:

/etc/csf/csf.pl -d 46.162.242.17 GeoIP Country Edition: AM, Armenia
/etc/csf/csf.pl -d 200.147.38.50 GeoIP Country Edition: BR, Brazil

This is great, but I want more than just output, I actually want the /etc/csf/csf.pl -d command to run, and block (just and only) the IP in the lines that match the country name, in the list.

I've tried various things with my limited knowledge of shell scripting, but so far, nothing seems to work. So is there some option for ECHO I am missing that would actually run the command rather than just printing out the line?

Upvotes: 45

Views: 154862

Answers (7)

manero
manero

Reputation: 151

You should pipe those echo and grep commands further like this:

...
echo -e "$runc $IP    $cc" | grep Algeria | sh
...

Lets take this command as an example:

$ echo -e "echo AAA\necho BBB\necho CCC"

echo AAA
echo BBB
echo CCC

From that I only need AAA:

$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA

echo AAA

Now to actually execute that echo AAA:

  • sh or bash
$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA | sh

AAA
  • xargs
$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA | xargs command

AAA

You can use tee if you actually need to both print and execute the command:

$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA | tee /dev/tty | sh

echo AAA
AAA

or

$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA | tee >(sh)

echo AAA
echo

xargs -t kinda works similarly:

$ echo -e "echo AAA\necho BBB\necho CCC" | grep AAA | xargs -t command

command echo AAA
AAA

xargs and sh/bash might not always work as expected, for example:

$ echo "echo echo | rev" | tee /dev/tty | xargs command

echo echo | rev
echo | rev

vs:

$ echo "echo echo | rev" | tee /dev/tty | sh

echo echo | rev
ohce

Using tee with multiple redirections:

$ echo "echo echo | rev" | tee >(sh) >(xargs command)

echo echo | rev
ohce
echo | rev

Upvotes: 0

Neeraj Verma
Neeraj Verma

Reputation: 771

Just put your command into parenthesis like this:

echo $(ls)

You can also have text before the command

echo "The date is $(date)"

For Example

echo "Enter Text Here $(Command Here)"

Upvotes: 52

Bobo
Bobo

Reputation: 9163

echo `pwd`

above command works for me.

Upvotes: 8

Flo Doe
Flo Doe

Reputation: 5381

There is a bash builtin eval, this executes commands like they were typed in at your shell. For example within your script you can do the following:

eval $(echo -e $runc $IP    $cc | grep Algeria)

This will process your echo in a subshell and the output will be executed like you typed it in your shell followed by enter.

See below exerpt from bash manual:

eval [arg ...] The args are read and concatenated together into a single command. This command is then read and executed by the shell, and its exit status is returned as the value of eval. If there are no args, or only null arguments, eval returns 0.

Upvotes: 10

Aaron Digulla
Aaron Digulla

Reputation: 328594

Use grep -E and a pattern instead:

$runc $IP    $cc | grep -E 'Algeria|Argentina|...'

Explanation: echo will print the command but not execute it. Just omit it to actually execute the command.

And instead of running the script 5 times, use grep to search for any of the five patterns at once.

And you should use

cc=$(geoiplookup $IP)

instead of backticks; it's safer.

Upvotes: 0

Syntax
Syntax

Reputation: 169

You can use eval to execute a string:

eval $cmdstring

Upvotes: 15

hek2mgl
hek2mgl

Reputation: 157967

A simple way that won't need modification of your script would be to pipe the command's output to another bash instance. Like this:

yourscript | bash -

The - tells bash that it should read commands from stdin.


However, if you are not searching for a quick solution, it is possible to build and execute the command dynamically as well. Like this:

cmd="ls"
if [ "foo" != "bar" ] ; then
    cmd="$cmd -a"
then

# ... and so on

# now execute it:
$cmd

Upvotes: 27

Related Questions