首页 > 解决方案 > eval 破坏 bash 脚本进程

问题描述

我有一个 bash 脚本,它根据来自网络浏览器的 GET 请求从 nodejs http-server 调用。bash 脚本的输出通过 http-server 返回到浏览器。

bash 脚本的目的是在文件中搜索网络浏览器提供的搜索词,并将搜索结果返回给 http-server,然后将结果发送到网络浏览器。

bash 脚本接收以下参数:

CS/NCS --> Case-sensitive search or not.  
OR/AND --> 'AND' or 'OR' search.  
one or more searchwords  

例如

'search_index.sh CS AND searchword1 searchword2'  
'search_index.sh NCS OR searchword1 searchword2 searchword3'  
 

egrep 用于搜索文件中的单词。

在第 26/29 行,执行“或”搜索。使用“OR”搜索字符串调用 Egrep。这完美地工作。搜索结果显示在网络浏览器中。

为了进行“与”搜索,我正在从第 33 行开始构建egrep 搜索字符串。在第 50 行,egrep 搜索字符串由eval 命令执行

如果我手动运行脚本,它工作正常。我可以看到写入控制台的搜索结果。

当由 http-server(网络浏览器)运行时,我没有看到任何返回到网络浏览器的内容

是否有另一种方法来执行 egrep 搜索字符串(第 50 行),这不会破坏搜索结果返回到 http-server?

1       #!/bin/bash
3       # search_index.sh v0.1 (p) april 2021
4       PARAMS=("$@")
5       T=1
6       declare -a SEARCH
7       for WORD in "${PARAMS[@]}"
8       do
9           if [[ $T -eq 1 ]]; then
10              CS_TYPE=$WORD
11              ((T=T+1))
12              continue
13          fi
14          if [[ $T -eq 2 ]]; then
15              LOG_TYPE=$WORD
16              ((T=T+1))
17              continue
18          fi
19          SEARCH+=("$WORD ")
20      done
21      INDEXFILE="/home/user/search/file.idx"
22      if [[ "$LOG_TYPE" = "OR" ]]; then
23          printf -v SEARCH_STR "%s" "${SEARCH[@]}"
24          SEARCH_STR=$( echo $SEARCH_STR | tr ' ' '|' )
25          if [[ "$CS_TYPE" = "NCS"  ]]; then
26              egrep --ignore-case $SEARCH_STR $INDEXFILE
27              exit
28          else
29              egrep $SEARCH_STR $INDEXFILE
30              exit
31          fi
32      else
33          if [[ "$CS_TYPE" = "NCS"  ]]; then
34              GREP_VAR="egrep --ignore-case "
35          else
36              GREP_VAR="egrep "
37          fi
38          I=0
39          for POS in "${SEARCH[@]}"
40          do
41              if [[ $I -eq 0 ]]; then
42                  GREP_STRING="$GREP_VAR ${SEARCH[$I]} $INDEXFILE "
43                  ((I=I+1))
44                  continue
45              else
46                  GREP_STRING+="| $GREP_VAR ${SEARCH[$I]} "
47                  ((I=I+1))
48              fi
49          done
50      eval $GREP_STRING
51      fi

1       // server.js
2       // HTTP-server for the bash search script ('search_index.sh').
3       // Example call: http://192.168.88.10:8888?SEARCH=NCS AND search_word1 search_word2
4       const { createServer } = require("http");
5       const { parse } = require("url");
6       const spawn = require('child_process').spawn;
7       function onRequest(request, response) {
8           var params = parse(request.url,true).query;
9           const proc = spawn('search_index.sh', [params.SEARCH]);
10          let output = '';                      
11          proc.stdout.on('data', (chunk) => {
12              output += chunk.toString();
13          });                                                                                 
14          proc.on('exit', () => {
15              response.writeHeader(200, {'Content-Type': 'text/plain'});                                                                              
16              response.end(output);
17              console.log(output);
18          });
19      };
20      createServer(onRequest).listen(8888);

更新:下面使用 execSync 的服务器代码正在运行。感谢 Taylor G. 的提示。

1 const { createServer } = require("http"); // http.createServe
2 const { parse } = require("url"); // url.parse
3 const { execSync } = require('child_process');

4 function onRequest(request, response) {

5    let result = execSync('search_index.sh').toString();
6    response.writeHeader(200, {'Content-Type': 'text/plain'});
7    response.end(result);

8 };
9 createServer(onRequest).listen(8118);

标签: node.jsbash

解决方案


您可以即时生成 AND egrep 结果,而不是在最后构建命令并使用 eval。

尝试将脚本中的第 33-50 行替换为以下内容。看看它是否适用于您的服务器。

I=0
RES=$(cat "$INDEXFILE")
for POS in "${SEARCH[@]}"
do
    if [[ "$CS_TYPE" = "NCS"  ]]; then
        RES=$(echo "$RES" | egrep --ignore-case ${SEARCH[$I]})
    else
        RES=$(echo "$RES" | egrep ${SEARCH[$I]})
    fi
    ((I=I+1))
done
echo "$RES"

推荐阅读