我創造了條件重現該問題,但一切都進展順利:
caller.pl:
#! /usr/bin/perl
$cmd = "echo 'a\\
b\\
c\\
d\\
e\\
f' | ~/doc/Answers/src/pltest/cmd1.csh";
sub system_tcsh
{
@args = ("tcsh", "-c", $cmd);
return system(@args);
}
system_tcsh
CMD1。CSH:
#! /bin/csh
echo "${0}(cmd1) $argv[*]"
set line1 = $<
set line2 = $<
set line3 = $<
setenv lineno 3
echo "cmd1: read: $line1 $line2 $line3"
./cmd2.csh
cmd2.csh:
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
./cmd3.csh
./cmd3.csh
set line6 = $<
echo " ${0}: Read: $line6"
cmd3.csh:
#! /bin/csh
# cmd3
set line = $<
echo " ${0}: Read: '$line'"
試運行:
[email protected] ~/doc/Answers/src/pltest $ ./caller.pl
/export/home/frayser/doc/Answers/src/pltest/cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.csh: Read: 'd'
./cmd3.csh: Read: 'e'
./cmd2.csh: Read: f
也許你可以修改此重新創建的麻煩,或者用它來實現你的解決方案。
-
UPDATE
這是再現Perl的標準輸入問題的最新情況,並提供了一個解決它。
用Perl版本更換CMD3給人的報道,有問題的結果是:
cmd3.pl替換cmd3.csh:
#! /usr/bin/perl
# cmd3
$_=<STDIN>;
chomp();
print " $0: Read: '$_'\n";
結果:使用cmd3.pl。在讀取「d」之後,不再有輸入可用。
./caller.pl
./cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.pl: Read: 'd'
./cmd3.pl: Read: ''
./cmd2.csh: Read:
爲了解決這個問題,CMD2更改爲只發送1線CMD3。所述line(1)命令輕易做到這一點:
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
line | ./cmd3.pl
line | ./cmd3.pl
set line6 = $<
echo " ${0}: Read: $line6"
這是cmd2.csh優化,以避免執行線命令的額外開銷。
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
set x = $<
echo $x | ./cmd3.pl
set y = $<
echo $y | ./cmd3.pl
set line6 = $<
echo " ${0}: Read: $line6"
這裏是更新cmd2.csh輸出。使用Perl的功能與使用csh作爲最終腳本時的功能相同:沒有丟失stdin。
./cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.pl: Read: 'd'
./cmd3.pl: Read: 'e'
./cmd2.csh: Read: f
[測試的binmode修復](http://stackoverflow.com/questions/3809357/how-do-i-recover-stdin-from-a-perl-script-that-was-called-from-a- CSH-腳本/ 3865528#3865528) 設置'binmode標準輸入, 「UNIX」'在* cmd3.pl *(並且沒有其他的變化)已經被驗證爲一個簡單的解決方案。 – frayser 2010-10-26 09:42:22