2

いくつかのコードに問題があり、誰かが助けてくれるかどうか疑問に思っています。

基本的に、データベースに対してisqlクエリを実行し、それをスカラー変数に割り当てようとしています。isqlコマンドは、パイプ記号として定義されている列区切り記号を使用します。

だから私はそれをそのように設定しています:

my $command = "isql -S -U -s| -i";
my $isql_output = `$command`;

isqlコマンドは単独で機能しますが、バックティックとして発行されると、パイプで停止します。$commandサブ文字列を使用して文字列を連結し、一重引用符を使用し、バックスラッシュを使用してアイテムをエスケープして-s\"\|\"みました。qxバックティックの代わりに使ってみました。

残念ながら、私は現在、アップグレードの範囲が限定された古いバージョンのperl(v5.6.1)を使用しているため、これを解決できるかどうかわかりません。

4

3 に答える 3

4

|シェルが特殊文字として認識しないように引用符を付ける必要があります。ふたつのやり方:

  1. を一重引用符で囲み-s|ます: '-s|'. Perl は、二重引用符で囲まれた文字列内の単一引用符をそのままにして、変更せずにシェルに渡します。
  2. を 2 つのバックスラッシュでエスケープ|します: -s\\|. なぜ2つ?最初のものは、Perl が次の文字を変更せずに渡すように指示することによって見られます。したがって、シェルは-s\|非常によく似た処理を認識して実行します。単一の文字を認識し、次の文字、特殊\文字を処理しないことを認識します。|
于 2012-12-10T12:49:51.427 に答える
1

問題は、コマンドがシェルを介して実行されていることです。これを回避するには、コマンドと引数を単一の文字列ではなくリストで渡します。バックティック コンストラクトはそれをサポートしていないため、open()代わりに関数を使用する必要があります。次のコードはテストしていませんが、アイデアは得られます。

my @command = (qw(isql -Sserver -Uuser -Ppassword -s| -w4096), '–i' . $file);
print join(' ', @command), "\n";
open(my $fh, '-|', @command)
  or die "failed to run isql command: $@\n";
my @isql_output = <$fh>;
close($fh);
my $isql_output = $isql_output[0]; chomp($isql_output);

15 年前のバージョンの Perl (Oracle ユーザーがよく使用するバージョン) を使用している場合、これがすべてサポートされるかどうかはわかりません。たとえば、chopの代わりに書く必要があるかもしれませんchomp

更新: 問題は Perl のバージョンではありませんが、ドキュメントによると、この構造は Windows ではサポートされていません。これは修飾する必要があります。私は Cygwin で Perl を使用しており、そこでは正常に動作しますが、Cygwin を使用できるかどうかはわかりません。

于 2012-12-10T14:05:43.477 に答える
0

一重引用符が機能するはずです。テスト用の perl スクリプトを実行してみてください:

my $cmd = "./test.sh -S -U -s '|' -i";
print `$cmd`;

test.sh を使用:

#!/bin/sh

echo $@

出力は-S -U -s | -i

于 2012-12-10T12:56:50.213 に答える