命令在舊版本的我們的代碼,我們從Perl的叫出來做一個LDAP搜索如下:系統調用在Perl
# Pass the base DN in via the ldapsearch-specific environment variable
# (rather than as the "-b" paramater) to avoid problems of shell
# interpretation of special characters in the DN.
$ENV{LDAP_BASEDN} = $ldn;
$lcmd = "ldapsearch -x -T -1 -h $gLdapServer" .
<snip>
" > $lworkfile 2>&1";
system($lcmd);
if (($? != 0) || (! -e "$lworkfile"))
{
# Handle the error
}
上面的代碼將導致一個成功的LDAP搜索,以及輸出該搜索將位於文件$lworkfile
中。
不幸的是,我們最近在此服務器上重新配置了openldap,因此在/etc/openldap/ldap.conf和/etc/ldap.conf中指定了「BASE DC =」。這種改變似乎意味着ldapsearch忽略LDAP_BASEDN環境變量,所以我的ldapsearch失敗。
我已經嘗試了幾個不同的修復,但沒有成功至今:
(1)我想回去使用「-b」參數ldapsearch的,但逃脫了shell元字符。我開始寫逃逸代碼:
my $ldn_escaped = $ldn;
$ldn_escaped =~ s/\/\\/g;
$ldn_escaped =~ s/`/\`/g;
$ldn_escaped =~ s/$/\$/g;
$ldn_escaped =~ s/"/\"/g;
,因爲我還沒有在Perl逃過那些正則表達式正確扔了一些Perl的錯誤(行號去匹配反引號正則表達式)。
Backticks found where operator expected at /tmp/mycommand line 404, at end of line
與此同時我開始懷疑這種方法,尋找一個更好的。
(2)然後我看到一些Stackoverflow問題(here和here),這表明提供了一個更好的解決方案。
下面的代碼:
print("Processing...");
# Pass the arguments to ldapsearch by invoking open() with an array.
# This ensures the shell does NOT interpret shell metacharacters.
my(@cmd_args) = ("-x", "-T", "-1", "-h", "$gLdapPool",
"-b", "$ldn",
<snip>
);
$lcmd = "ldapsearch";
open my $lldap_output, "-|", $lcmd, @cmd_args;
while (my $lline = <$lldap_output>)
{
# I can parse the contents of my file fine
}
$lldap_output->close;
我用的方法有兩個問題,(2):
一)調用打開或系統參數數組不會讓我過去> $lworkfile 2>&1
到命令,所以我不能停止ldapsearch的輸出發送到屏幕上,這讓我的輸出看起來很醜陋:
Processing...ldap_bind: Success (0) additional info: Success
b)我不知道如何選擇哪個位置(即路徑和文件名稱)傳遞給傳遞給open
的文件句柄,即我不知道$lldap_output
在哪裏。我可以移動/重命名它,還是檢查它以找出它的位置(或它是否實際上未保存到磁盤)?
根據與(2),這讓我覺得我應該返回到方法(1),但我不是很清楚如何
這是在覈心Perl模塊?該解決方案看起來不錯,但不幸的是,Perl報告「無法在@INC中找到IPC/Run3.pm」。我猜我需要安裝這個IPC-Run3-0.044模塊,我寧願避免這樣做,因爲我必須對服務器進行構建/安裝更改。 – 2010-12-10 22:28:57
不,IPC :: Run3不是核心模塊。 – cjm 2010-12-10 22:58:31