# Output Exec Script

**URL:** <https://discuss.elastic.co/t/output-exec-script/2750>\
**Category:** Logstash\
**Created:** [June 16, 2015, 12:24am UTC](https://discuss.elastic.co/t/output-exec-script/2750 "2015-06-16T00:24:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 16, 2015, 12:24am UTC](https://discuss.elastic.co/t/output-exec-script/2750/1 "2015-06-16T00:24:32Z")

</div>

Hello, I’m attempting to read a log file and run a script as output.

The script accepts STDIN data, but I don’t think I’ve set up the log stash configs properly since the script never gets executed the way it’s currently set up. (I've tested the script without logstash and it's functioning properly, I'm guessing there's something amiss in the way I've set it up.)

```
input {
    file {  
        path => "/var/logs/foo.log"
        codec => "plain"
    } 
}

output {
    exec {
        command => "php /bin/scripts/process.php"
    }
}
```

---

<div class="post-metadata">

**Author:** ![warkolm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/warkolm/32/39224_2.png) [@warkolm](https://discuss.elastic.co/u/warkolm)\
**Post date:** [June 16, 2015, 12:28am UTC](https://discuss.elastic.co/t/output-exec-script/2750/2 "2015-06-16T00:28:36Z")

</div>

Try using the full path to the script?

---

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 16, 2015, 12:30am UTC](https://discuss.elastic.co/t/output-exec-script/2750/3 "2015-06-16T00:30:59Z")

</div>

Sorry, I actually am, I changed it for the sake of this question. Both file paths are fully qualified. (I've edited the question to include full paths).

---

<div class="post-metadata">

**Author:** ![warkolm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/warkolm/32/39224_2.png) [@warkolm](https://discuss.elastic.co/u/warkolm)\
**Post date:** [June 16, 2015, 12:39am UTC](https://discuss.elastic.co/t/output-exec-script/2750/4 "2015-06-16T00:39:31Z")

</div>

Does LS have privs to execute that script? Try enabling debug when you run LS as well.

However if you are running this a few times and not changing the input path, chances are you are running into a sincedb problem and the file will not be read which means the script won't be run.

---

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 16, 2015, 1:02am UTC](https://discuss.elastic.co/t/output-exec-script/2750/5 "2015-06-16T01:02:49Z")

</div>

I've been executing this repeatedly during tests:

```
echo "ABC" >> foo.log 

```

I just added this to my output:

```
stdout {
    codec => rubydebug
}

```

This is what I see in the logstash.stdout:

```
{
    "message" => "ABC",
    "@version" => "1",    
    "@timestamp" => "2015-06-16T00:58:16.577Z",
    "host" => "dev.neoform",
    "path" => "/var/logs/foo.log"
}

```

I tested the configs, I says nothing is wrong.

Maybe I'm making a mistake here, the command being run, is logstash sending it any data via STDIN? Do I need to pipe it explicitly?

---

<div class="post-metadata">

**Author:** ![Joshua\_Rich](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joshua_rich/32/44953_2.png) [@Joshua\_Rich](https://discuss.elastic.co/u/Joshua_Rich)\
**Post date:** [June 16, 2015, 6:47am UTC](https://discuss.elastic.co/t/output-exec-script/2750/6 "2015-06-16T06:47:25Z")

</div>

Yes, you'll need to pass one or more of the fields that Logstash creates to the script as command-line arguments. This doesn't happen automagically. So try the following output:

```auto
output {
    exec {
        command => "php /bin/scripts/process.php %{message}"
    }
}

```

The `exec` as you had it just guarantees that it will execute for each document processed by logstash, not that it will process each document. So you can use the exec to do something wholly separate from each document if you wanted.

---

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 16, 2015, 11:45am UTC](https://discuss.elastic.co/t/output-exec-script/2750/7 "2015-06-16T11:45:48Z")

</div>

Is there a more appropriate way to pass STDIN content to a script in this way? If I do:

```
echo "%{message}" | php /bin/scripts/process.php

```

That would work, but doesn't seem very secure...

---

<div class="post-metadata">

**Author:** ![Joshua\_Rich](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joshua_rich/32/44953_2.png) [@Joshua\_Rich](https://discuss.elastic.co/u/Joshua_Rich)\
**Post date:** [June 17, 2015, 1:13am UTC](https://discuss.elastic.co/t/output-exec-script/2750/8 "2015-06-17T01:13:00Z")

</div>

Not secure in the sense that you can see "%{message}" briefly in the process table when the exec runs or in the sense that you passing arbitrary data to a script?

For the former, there is not much you can do. For the latter, this would be something you ultimately need to handle yourself by making sure your script isn't prone to common security issues.

If you can eliminate what the script is doing with a combination of filters and outputs in Logstash then that's your best bet. If you can't replace the logic in the script, you could modify it to either listen on a TCP/UDP port or UNIX socket and then use either the `tcp`, `udp` or `file` (for a socket) outputs respectively to solve the first security problem above.

---

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 17, 2015, 1:19am UTC](https://discuss.elastic.co/t/output-exec-script/2750/9 "2015-06-17T01:19:57Z")

</div>

Well, it's insecure in the sense that I'm just echoing data into a command and executing. Considering the messages are logs from a web server, a lot of the data I'm pumping in is user generated.

I was hoping there was a way to execute a command and have logstash pass the data via STDIN without having to pipe it in a command (as shown above), at least not without first escaping the content of the message to make sure it doesn't have unescaped quotes in it, as that would break this:

```
echo "%{message}" | php /bin/scripts/process.php
```

---

<div class="post-metadata">

**Author:** ![Joshua\_Rich](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joshua_rich/32/44953_2.png) [@Joshua\_Rich](https://discuss.elastic.co/u/Joshua_Rich)\
**Post date:** [June 17, 2015, 1:38am UTC](https://discuss.elastic.co/t/output-exec-script/2750/10 "2015-06-17T01:38:25Z")

</div>

Making sure STDIN is properly quoted is only solving one aspect of security here. Ultimately, your fundamental problem is you are passing arbitrary data to a script that executes on the server running Logstash ☹

I just realised you might be able to use the `pipe` output, but this isn't any more secure than using `exec`.

---

<div class="post-metadata">

**Author:** ![neoform](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/neoform/32/680_2.png) [@neoform](https://discuss.elastic.co/u/neoform)\
**Post date:** [June 17, 2015, 3:25am UTC](https://discuss.elastic.co/t/output-exec-script/2750/11 "2015-06-17T03:25:58Z")

</div>

If the input was being passed via STDIN, there wouldn't be any risk, I can easily handle the input in a safe way via the script. The issue is how to get it piped into the script without just dumping it into the command-line.

I believe the `pipe` output only works if I have a continuously running command listening to the pipe, no?

I was hoping to be able to run this script once for each line in the log file...

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 5:37am UTC](https://discuss.elastic.co/t/output-exec-script/2750/12 "2017-07-06T05:37:15Z")

</div>


