[linux-l] Das "Unschoene-Zeichen-Problem" (was: Portable Shell-Scripte)

Mike Dornberger Mike.Dornberger at gmx.de
Di Dez 12 18:36:57 CET 2006


Hallo Benjamin,

On Tue, Dec 12, 2006 at 06:52:24AM +0100, Benjamin Schieder wrote:
> On 11.12.2006 23:56:30, Mike Dornberger wrote:

> > aha, die bash benutzt <<<, um das expandierte Wort dahinter dem Kommando
[...]

> Ja, die bash2 hat da allerdings noch einen Bug drin:
> 
> blindcoder at fuzzy:~$ cat <<< $foo
> Segmentation fault (core dumped)
> blindcoder at fuzzy:~$ rm core
> blindcoder at fuzzy:~$ cat <<< "$foo"
> 
> Leere Variable ohne "" loest einen Segfault aus. Status: Won't Fix.

aha, gut zu wissen. Naja, ungequotete $foo sind ja fast immer ein Problem,
also (fast) immer quoten, schadet ja (meist) nix. :-)

> > Da [2]echo lt. Spezifikation der OpenGroup -n nicht "wie gewohnt"
> > unterstützen muß, sollte man die Zeile, so man denn auf einfache
> > Portierung/ Plattformunabhängigkeit wert legt, in
> > 
> >  newname ="$( printf %s "${newname}" | tr '[[:upper:]]' '[[:lower:]]' )"
> 
> oder einfach:
> $nemnawe="$( echo "${newname}" | tr '[[:upper:]]' '[[:lower:]]' )"

Ja, mir ging es um den Spezialfall, wenn eine Datei mal mit \n endet. Wie
ich eben unter [1] gelernt habe, werden aber bei Command Substitution alle
Newlines am Ende weggeschmissen, also auch die, die zum Dateinamen gehören.

  [1] http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03

Da steht noch, daß der IFS eingebettete Newlines beeinflussen kann, wenn
Field-Splitting passiert. Sollte ja aber nicht, wenn das $( command )-
Konstrukt gequotet ist, oder?

Also "Trick": Am Ende ein "schönes" Zeichen (z. B. .) mit ausgeben und das
anschließend per ${name%word}-Konstrukt löschen:

new="$(printf "abc\ndef\n\n\n." | tr '[[:lower:]]' '[[:upper:]]' )"; printf \
%s "$new"; new="${new%.}"; printf %s "$new"

Ich habe in dem Beispiel mal printf als erstes mit benutzt, da [2]`echo -e'
auch nicht standardisiert ist. Und wie ich gerade lese ist echo auch
ziemlich böse, da es durchaus Escape-Sequenzen auch ohne -e interpretieren
kann.

  [2] http://www.opengroup.org/onlinepubs/000095399/utilities/echo.html

Also:

newname="$( printf %s "${newname}." | tr '[[:upper:]]' '[[:lower:]]' )"
newname="${newname%.}"

Hm, irgendwelche Spezialfälle vergessen?

Grüße,
 Mike




Mehr Informationen über die Mailingliste linux-l