Seltsamkeiten mit Shell-Backticks und perl -e

Seltsamkeiten mit Shell-Backticks und perl -e

am 13.12.2006 12:26:06 von Jan Schmidt

Hallo zusammen,

ich schaffe es nicht, ein beliebiges "perl -e"-Kommando einer
Shell-Variablen zuzuweisen und diese dann in Backticks auszuführen. Ich
bin mir noch etwas unsicher, ob es sich tatsächlich um ein Perlproblem
handelt. Zwei Indizien sprechen meiner Ansicht nach dafür: 1. Es gibt
eine Perl-Fehlermeldung, 2. Mit einem einfachen anderen Programm
funktioniert es.

Zum besseren Verständnis mal ein paar Beispiele:

$ t="perl -lwe 'print 1'"; echo $t; echo `$t`
perl -lwe 'print 1'
Can't find string terminator "'" anywhere before EOF at -e line 1.

$ t="perl -lwe print\ 1"; echo $t; echo `$t`
perl -lwe print\ 1
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

$ t="perl -lwe print\\ 1"; echo $t; echo `$t`
perl -lwe print\ 1
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

$ perl -lwe print\ 1
1

$ t="perl -lwe print 1"; echo $t; echo `$t`
perl -lwe print 1
Use of uninitialized value in print at -e line 1.

$ t="echo abc"; echo $t; echo `$t`
echo abc
abc

Habe meine Tests mit der Bash gemacht, das gleiche lässt sich aber auch
mit der tcsh erreichen. Kann mir das obige Verhalten jemand erklären?

Gruß, Jan

Re: Seltsamkeiten mit Shell-Backticks und perl -e

am 13.12.2006 19:26:15 von Ferry Bolhar

Jan Schmidt:

> Habe meine Tests mit der Bash gemacht, das gleiche lässt sich aber auch
> mit der tcsh erreichen. Kann mir das obige Verhalten jemand erklären?

Jein - auf alle Fälle scheint es ein Shell-Problem zu sein.

Wenn du mit

set -x

das Logging aufdrehst, siehst du, was Perl wirklich vorgeworfen bekommt:

$t="perl -lwe 'print 1'" (Doppelquotes außen, Einfachquotes innen)
+ t='perl -lwe '\''print 1'\''' (die Doppelquotes werden durch je zwei
Einfachquotes ersetzt)
$ echo `$t`
++ perl -lwe ''\''print' '1'\''' (das sind alles Einfachquotes!)
Can't find string terminator "'" anywhere before EOF at -e line 1
+ echo
$

Noch befremdlicher ist es umgekehrt:

$ t='perl -lwe "print 1"' (Einfachquotes außen, Doppelquotes innen)
+ t='perl -lwe "print 1"' (Sieht ja noch ganz vernünftig aus)
$ echo `$t`
++ perl -lwe '"print' '1"' (Vor und nach jedem Argument wird ein
Einfachquote eingefügt!)
Can't find string terminator '"' anywhere before EOF at -e line 1
+ echo
$

Warum das so ist, kann wohl nur ein Shell-Spezialist beantworten.

> $ t="perl -lwe print 1"; echo $t; echo `$t`
> perl -lwe print 1
> Use of uninitialized value in print at -e line 1.

Das ist nachvollziehbar, da "print 1" nicht gequoted ist, -e aber den
gesamten Befehl als ein Argument erwartet. An Perl wird also nur
"print" übermittelt, was einem "print $_" entspricht, und da diese
Variable nicht gesetzt ist und du mit -w Warnungsmeldungen ange-
fordert hast, bekommst du auch eine solche. ;-)

Möglicherweise kann man mit einer der zahllosen Bash-Optionen
das Qouting-Verhalten steuern. Mir kommt es auch recht seltsam
vor. Aber ich bin kein Shell-Experte.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Seltsamkeiten mit Shell-Backticks und perl -e

am 13.12.2006 20:22:49 von Slaven Rezic

Jan Schmidt writes:

> Hallo zusammen,
>
> ich schaffe es nicht, ein beliebiges "perl -e"-Kommando einer
> Shell-Variablen zuzuweisen und diese dann in Backticks auszuführen. Ich
> bin mir noch etwas unsicher, ob es sich tatsächlich um ein Perlproblem
> handelt. Zwei Indizien sprechen meiner Ansicht nach dafür: 1. Es gibt
> eine Perl-Fehlermeldung, 2. Mit einem einfachen anderen Programm
> funktioniert es.
>
> Zum besseren Verständnis mal ein paar Beispiele:
>
> $ t="perl -lwe 'print 1'"; echo $t; echo `$t`
> perl -lwe 'print 1'
> Can't find string terminator "'" anywhere before EOF at -e line 1.
>
> $ t="perl -lwe print\ 1"; echo $t; echo `$t`
> perl -lwe print\ 1
> syntax error at -e line 1, at EOF
> Execution of -e aborted due to compilation errors.
>
> $ t="perl -lwe print\\ 1"; echo $t; echo `$t`
> perl -lwe print\ 1
> syntax error at -e line 1, at EOF
> Execution of -e aborted due to compilation errors.
>
> $ perl -lwe print\ 1
> 1
>
> $ t="perl -lwe print 1"; echo $t; echo `$t`
> perl -lwe print 1
> Use of uninitialized value in print at -e line 1.
>
> $ t="echo abc"; echo $t; echo `$t`
> echo abc
> abc
>
> Habe meine Tests mit der Bash gemacht, das gleiche lässt sich aber auch
> mit der tcsh erreichen. Kann mir das obige Verhalten jemand erklären?

Möchtest du vielleicht eval in der Shell statt der Backticks
verwenden?

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

Lost in your Tk widget tree? Try
http://user.cs.tu-berlin.de/~eserte/src/perl/Tk-WidgetDump/

Re: Seltsamkeiten mit Shell-Backticks und perl -e

am 13.12.2006 21:56:41 von hjp-usenet2

On 2006-12-13 18:26, Ferry Bolhar wrote:
> Jan Schmidt:
>> Habe meine Tests mit der Bash gemacht, das gleiche lässt sich aber auch
>> mit der tcsh erreichen. Kann mir das obige Verhalten jemand erklären?
>
> Jein - auf alle Fälle scheint es ein Shell-Problem zu sein.
>
> Wenn du mit
>
> set -x
>
> das Logging aufdrehst,

Das ist immer eine gute Idee, wenn Shell-Scripts seltsame Dinge tun.

> siehst du, was Perl wirklich vorgeworfen bekommt:
>
> $t="perl -lwe 'print 1'" (Doppelquotes außen, Einfachquotes innen)
> + t='perl -lwe '\''print 1'\''' (die Doppelquotes werden durch je zwei
> Einfachquotes ersetzt)
> $ echo `$t`
> ++ perl -lwe ''\''print' '1'\''' (das sind alles Einfachquotes!)
> Can't find string terminator "'" anywhere before EOF at -e line 1
> + echo
> $
>
> Noch befremdlicher ist es umgekehrt:
>
> $ t='perl -lwe "print 1"' (Einfachquotes außen, Doppelquotes innen)
> + t='perl -lwe "print 1"' (Sieht ja noch ganz vernünftig aus)
> $ echo `$t`
> ++ perl -lwe '"print' '1"' (Vor und nach jedem Argument wird ein
> Einfachquote eingefügt!)
> Can't find string terminator '"' anywhere before EOF at -e line 1
> + echo
> $

Das ist ziemlich genau das gleiche, die Ausgabe sieht nur etwas anders
aus. In beiden Fällen wird perl mit 3 Argumenten aufgerufen:

»-lwe«, »'print«, »1'« im ersten,
»-lwe«, »"print«, »1"« im zweiten Fall.

Warum die Bash innerhalb der `` zwar die Variable expandiert und ein
Wordsplit durchführt, dabei aber die Quotes ignoriert, ist mir auch nach
nochmaligem Lesen der Manpage nicht ganz klar.

Wie man es richtig macht, hat Slaven ja schon geschrieben. In
komplizierteren Fällen kann es von Vorteil sein, temporär ein
Shell-Script zu erzeugen und das auszuführen. Dann ist es aber
wahrscheinlich einfacher, gleich Perl zu verwenden. (HJP's Regel zur
Shell-Programmierung: Wenn man mehr als 10 Minuten überlegen muss, wie
man einen gewünschten Effekt mit der Shell erreicht, werfe man das ganze
Shell-Script weg und schreibe statt dessen ein Perl-Script)

hp


--
_ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
|_|_) | Sysadmin WSR | > ist?
| | | hjp@hjp.at | Was sonst wäre der Sinn des Erfindens?
__/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd

Re: Seltsamkeiten mit Shell-Backticks und perl -e

am 14.12.2006 02:17:14 von David Haller

Slaven Rezic wrote:
> Jan Schmidt writes:
>> Zum besseren Verständnis mal ein paar Beispiele:
>>
>> $ t="perl -lwe 'print 1'"; echo $t; echo `$t`
>> perl -lwe 'print 1'
>> Can't find string terminator "'" anywhere before EOF at -e line 1.
[..]
> Möchtest du vielleicht eval in der Shell statt der Backticks
> verwenden?

Nein. Will er nicht. Entweder man packt das Ganze anders in Variablen,
oder schreibt besser gleich alles in perl.

Zu ersterem (ungetestet!):

$ set -x; t='print "a b";'; echo "`perl -lwe \"$t\"`"
+ t=print "a b";
++ perl -lwe 'print "a b";'
+ echo 'a b'
a b
$

Bzw.:

$ set -x; t='print "a b";'; echo "$(perl -lwe "$t")"

wenn man $() statt `` verwenden will, was u.U. empfehlenswert ist.

Alternativ koennte man in der Bash auch ein Array verwenden.

HTH,
-dnh

--
PANIC YE NOT: go have a drink