简单的rest api服务器将参数传递给shell脚本并在shell上执行它

时间:2012-08-16 23:07:17

标签: ruby perl api sed cgi

我只想拥有一个休息api服务器,我可以通过URL调用它来更新文件,就是这样。

这是文件:

mytextfile:
       key1 = value1
       key2 = value2
  1. 在客户端上,将运行一个脚本,将一个或多个字符串发送到API服务器。
  2. API服务器将接收它们,例如/update.script?string1="blah"&string2="fun"(假装其网址编码)
  3. 然后服务器应解析这些字符串,然后调用exec函数或其他脚本,甚至在执行某些sed命令来更新文件的系统上
  4. 语言或实施并不重要。

    寻找新的想法。

    所有建议都表示赞赏。

2 个答案:

答案 0 :(得分:2)

我不明白:你的问题到底是什么?

我解决问题的方法“使用url编码的参数修改cgi脚本中的文件”将是:

  1. 选择您喜欢的语言并开始编码,在我的情况下使用Perl。

    #!/usr/bin/perl
    use strict; use warnings;
    
  2. 获取所有参数。我将在这里使用Perl的CGI模块:

    use CGI::Carp;
    use CGI;
    my $cgi = CGI->new;
    
    # assuming we don't have multivalued fields:
    my %arguments = $cgi->Values; # handles (almost) *all* decoding and splitting
    # validate arguments
    # send back CGI header to acknowledge the request
    # the server will make a HTTP header from that
    
  3. 现在用它们调用一个特殊的子程序/函数......

    updateHandler(%arguments);
    ...;
    my $filename = 'path to yer file name.txt';
    sub updateHandler {
       my %arguments = @_;
       # open yer file, loop over yer arguments, whatever
    
       # read in file
       open my $fileIn, '<', $filename or die "Can't open file for reading";
       my @lines = <$fileIn>;
       close $fileIn;
    
       # open the file for writing, completely ignoring concurrency issues:
       open my $fileOut, '>', $filename or die "Can't open file for writing";
    
       # loop over all lines, make substitutions, and print it out
       foreach my $line (@lines) {
          # assuming a file format with key-value pairs
          # keys start at the first column
          # and are seperated from values by an '=',
          # surrounded by any number of whitespace characters
          my ($key, $value) = split /\s*=\s*/, $line, 2;
    
          $value = $arguments{$key} // $value;
          # you might want to make sure $value ends with a newline
    
          print $fileOut $key, " = ", $value;
       }
    }
    

    不要使用这个相当不安全和次优的代码!我刚刚写了这篇文章,证明这并不复杂。

  4. ...或者提供一种将参数发送到另一个脚本的方法(尽管Perl非常适合文件操作任务)。选择qw{}systemexec命令之一,具体取决于脚本需要的输出,或决定使用open my $fh, '|-', $command模式将参数传递给脚本open

  5. 至于运行此脚本的服务器:Apache看起来很好,除非你有非常特殊的需求(你自己的协议,单线程,低安全性,低性能),在这种情况下你可能想要编码自己的服务器。使用HTTP::Daemon模块,您可以为简化服务器管理&lt; 50行。

    使用Apache时,我强烈建议使用mod_rewrite将/path放入PATH_INFO环境变量中。使用一个脚本来表示整个REST API时,可以使用PATH_INFO选择许多方法/子例程/函数中的一个。这也消除了在URL中命名脚本的需要。

    例如,转动网址

    http://example.com/rest/modify/filename?key1=value1
    

    /cgi-bin/rest-handler.pl/modify/filename?key1=value1
    

    在Perl脚本中,我们会$ENV{PATH_INFO}包含/modify/filename

  6. 这有点以Perl为中心,但只需选择您熟悉的任何语言并开始编码,利用您在途中可以使用的任何模块。

答案 1 :(得分:1)

我会使用更新的Perl框架,例如Mojolicious。如果我创建一个文件(test.pl):

#!/usr/bin/env perl

use Mojolicious::Lite;
use Data::Dumper;

my $file = 'file.txt';

any '/' => sub {
  my $self = shift;
  my @params = $self->param;

  my $data = do $file;
  $data->{$_} = $self->param($_) for @params;

  open my $fh, '>', $file or die "Cannot open $file";

  local $Data::Dumper::Terse = 1;
  print $fh Dumper $data;

  $self->render( text => "File Updated\n" );
};

app->start;

然后运行morbo test.pl

并访问http://localhost:3000/?hello=world(或运行./test.pl get /?hello=world

然后我进入file.txt

{
  'hello' => 'world'
}

等等。