2017-03-18 17 views
2

にevalingのための文字列を作成するようbashでそれをevalingためperl内の文字列を準備したい:それは印刷し安全な方法は、bashの

str="$(perl -E '$sq=chr(047);say qq{var1=${sq}hello world${sq}}')" #this just for demo - the real perl scirpt is ofcourse real complex script ... 
echo "got for eval: [[$str]]" 
eval "$str" 
echo "var1  : [[$var1]]" 

got for eval: [[var1='hello world']] 
var1  : [[hello world]] 

またはコースevalは危険ですので、 perlスクリプトはいくつかの準備をする必要があります。

ことの一つは、'"'"'と値のすべての'(単一引用符)を置き換える、ですので、vardon't do thisを割り当てるとき

var='don'"'"'t do this' #safe for eval. 

がここに私が従うべきいくつかのより多くのconsidartionsされているような、それが印刷されなければなりません変数assingnmentを準備するためのperlスクリプト(var='some content'安全のための文字列eval?私の本当のスクリプトから

断片:

#!/usr/bin/env perl 
use strict; 
use warnings; 

sub make_var { 
    my($name, $value) = @_; 
    die "Wrong variable name [$name]" if $name =~ /\W/; 
    my $sval = sanitise($value); 
    #warn qq{$name='$sval'\n}; 
    print qq{$name='$sval'\n}; 
} 

sub sanitise { 
    my $str = shift; 
    $str =~ s/'/'"'"'/gs; 
    # what more i should do here? 
    return $str; 
} 

#usage 
make_var('var1', q{some 
multiline 
value 
where i should'nt miss 
escape the single quotes}); 

evalのための安全な文字列を出力します。この背後にある論理的根拠:

var1='some 
multiline 
value 
where i should'"'"'nt miss 
escape the single quotes' 

EDIT iの値がperlスクリプトによって生成される多くの変数を、必要bash

。 1つの変数については、私はできる:

var="$(my_script)" 

しかし、私はbashスクリプトでは多くの変数が必要です。 Doing

var1="$(my_script some args)" 
var2="$(my_script other args)" 
... 
var10="$(my_script bla bla)" 

はかなり高価で遅いです。 (perlスクリプトは多くのことを行いますが、最も高価です - ウェブからjsonを取り出します...)したがって、呼び出しの数を1つに減らしたい - そのような必要があるのはevalです。

';date;':  var2=''"'"';date;'"'"':' # the escaping solves it 
$(date)  var='$(date)'   # safe 
+0

なぜあなたはbashで物事をevalしたいですか? –

+1

'bash'スクリプトに返す値を絶えず計算するのではなく、単一のPerlスクリプトを書くべきでしょう。 – chepner

+0

@chepner - heh、true。残念ながら、bashスクリプトは私の責任ではありません。したがって、完全にperlに書き換えることはできません。 – kobame

答えて

5

これは恐ろしい提案である:

ソンムは、パターンは私の心に入ってくるwerid。私はあなたがevalを忘れ、その代わりに あなたのPerlコードを書いて、値をstdoutにスペースで区切られた文字列で返すようにすることをお勧めします。そして、あなたがあなたの代わりに

read -r -a vars <<< $(perl -E '...print "val1 val2 val3\n"') 

配列に読み込むことができ好む場合ならば今の値はvars[0]vars[1]vars[2]

あるbashの

read -r var1 var2 var3 rest <<< $(perl -E '...print "val1 val2 val3\n"') 

readを使用して、それを分割することができます値に空白が含まれる可能性がある場合は、データでこれまで使用されていない別の区切り文字(カンマ,やコロン:など)を使用してください。IFSその文字を読み込む前に

+0

優秀!私はあなたの考えに基づいて解決策を作りました。どうもありがとうございました。 – kobame

0

ありがとう@ボロディン!ライン毎

<varname><any variable content> 

ので、私は正確に定義されている正規表現解析可能な構造:

のperlスクリプトは、フォームでnull terminatedラインのセリエAを出力します。あなたの考えに基づいて、私は、このソリューションを作成しました。

bashの機能を変数に印刷すると、指定した順序でreadコマンドを実行する必要はありません。

bashスクリプト:

fetch_external_data() { 
    perl p4.pl 
} 

read_data() { 
    regex='^<([a-zA-Z0-9_][a-zA-Z0-9_]*)><(.*)>$' 
    while IFS= read -d '' -r line 
    do 
     if [[ "$line" =~ $regex ]] 
     then 
      printf -v "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" 
     else 
      echo "Ignoring strange line: $line" >&2 
     fi 
    done < <(fetch_external_data) 
} 

read_data 
echo "var1: [[$var1]]";echo 
echo "var2: [[$var2]]";echo 
echo "var3: [[$var3]]";echo 

とPerlスクリプト:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Getopt::Std; 

our $opt_d; 
getopts('d'); 

sub make_var { 
    my($name, $value) = @_; 
    die "Wrong variable name [$name]" if $name =~ /\W/; 
    return "<$name><$value>" . ($opt_d ? "\n" : "\0"); 
} 

my $all = make_var('var1','hello'); 
$all .= make_var('var2', q{some 
multiline 
value '" bla 
here $(date) "'}); 
$all .= make_var('var3', 'world'); 

binmode(STDOUT); 
print $all; 
0

あなたはシェルリテラルに任意のテキストを変換するString::ShellQuoteshell_quoteを使用することができます。

eval "$(
    perl -e' 
     use String::ShellQuote qw(shell_quote); 
     my $str = qq{Some dangerous symbols: \\\x27"!}; 
     my $cmd = "var1=" . shell_quote($str); 
     print($cmd); 
    ' 
)" 
printf "%s\n" "$var1" 

出力:

Some dangerous symbols: \'"! 
0

は、ここで私が使用しているものです:

sub shellquote1 
{ 
    return $_ 
     unless m([^@%\w:,./=+-]); 
    s/\'/\'\\\'\'/g; 
    return "'$_'"; 
} 

sub shellquote 
{ 
    return join " ", map { shellquote1 } @_; 
} 

print shellquote(@ARGV); 
関連する問題