• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[solved] Wie die Metacharakterinterpretation unterbinden?

framp

Moderator
Teammitglied
Anbei ein kleines bash Snippet welches einfach Strings auf eine maximale Länge mit bestimmten Zeichen padden soll. Leider gibt es da ein Problem: Da der auszugebene String ein shell Metacharater '*' hat wird der interpretiert.
Die gewünschte Ausgabe habe ich im Snippet im Kommentar reingeschrieben. Weiss jemand wie ich die shell Interpretation verhindern kann? Ich habe schon verschiedene Dinge probiert wie Einsatz von \ als Escape char und diverse andere Versuche - leider kein Erfolg :???:

Code:
#!/bin/bash

SEPARATOR="==================================================="

function colorate () {  # message

   local msgLength
   local seplength
   local rest
   msgLength=${#*}
   sepLength=${#SEPARATOR}
   let rest=$sepLength-$msgLength-1-5
   if [[ $rest < 0 ]]; then
      rest=0
   fi

   echo ${SEPARATOR:0:4} $* ${SEPARATOR:0:$rest}
}

touch eins1
touch eins2

f=("eins*" "zwei*" "drei*")

i=0
# print string        '==== eins* ==============================================='
# ausgabe ist aber '==== eins1 eins2 ==========================================='
m=`colorate "\${f[$i]}"`
echo $m

# print string '==== eins1 eins2 ==========================================='
# ausgabe ist auch '==== eins1 eins2 ==========================================='
m=`colorate ${f[$i]}`
 
Genau dafür hasse ich die Shell:
Code:
#!/bin/bash

SEPARATOR="==================================================="

function colorate () {  # message

   local msgLength
   local seplength
   local rest
   msgLength=${#*}
   sepLength=${#SEPARATOR}
   let rest=$sepLength-$msgLength-1-5
   if [[ $rest < 0 ]]; then
      rest=0
   fi

   echo "${SEPARATOR:0:4} $* ${SEPARATOR:0:$rest}"
}

touch eins1
touch eins2

f=('eins*' 'zwei*' 'drei*')

i=0
# print string        '==== eins* ==============================================='
# ausgabe ist aber '==== eins1 eins2 ==========================================='
m=`colorate "${f[$i]}"`
echo "$m"

# print string '==== eins1 eins2 ==========================================='
# ausgabe ist auch '==== eins1 eins2 ==========================================='
echo "${f[$i]}"
;)
Erklärung:
Code:
#!/bin/bash

a='*'
echo "$a"

f=('eins*' 'zwei*' 'drei*')
echo "${f[0]}"
Gruß
 
OP
framp

framp

Moderator
Teammitglied
Danke für den Tip. Leider funktioniert das in Deinem Beispiel - aber nicht in meinem Script in dem es noch verschachtelte Funktionsaufrufe mit dem String als Rückgabeparameter gibt.

Mein Bypass ist jetzt, dass ich "'" vor und nach dem String vor der Ausgabe stelle. Die ' sieht man dann zwar auch in der Ausgabe - aber wenigstens wird nichts mehr von der Shell expanded.
 
OP
framp

framp

Moderator
Teammitglied
Meinst Du extquote? Aus der man page dazu werde ich leider nicht so ganz schlau.
If set, $'string' and $"string" quoting is performed
within ${parameter} expansions enclosed in double
quotes. This option is enabled by default.
Ich weiss nicht was '$'string' and $"string" quoting' ist. Ebensowenig weiss ich was '${parameter} expansions enclosed in double quotes' ist :???:
 
A

Anonymous

Gast
Probiers mal so hier
Code:
#!/bin/bash

touch eins1
touch eins2
f=('eins*' 'zwei*' 'drei*')

for i in 0 1 2 3
do
echo ${f[$i]}
done

set -f

for i in 0 1 2 3
do
echo ${f[$i]}
done

set +f

for i in 0 1 2 3
do
echo ${f[$i]}
done
oder global für das ganze Script abschalten wenn sonst nichts mit Dateien in diesem Script gemacht wird mit
Code:
#!/bin/bash -f 
.....
robi
 
Hi framp, schau mal hier:

http://www-user.tu-chemnitz.de/~hot/unix_linux_werkzeugkasten/bash.html


Ich hatte mir dein Problem erst nicht richtig durchgelesen. Sorry dafür... Aber dafür jetzt aus eine Erklärung aus meiner
Sicht. Schau mal in dem Beispiel unten.
( -f/noglob ist eine Option )
Das Problem entsteht, wenn das "echo" deine Variablen als getrennte Parameter erhält. Dann greift "Pathname expansion"
Wenn Du in deinem Skript an den beiden passenden Stellen "" verwendest, werden Dateinamen nicht komplettiert.


Code:
#!/bin/bash

SEPARATOR="==================================================="

function colorate () {  # message

   local msgLength
   local seplength
   local rest
   msgLength=${#*}
   sepLength=${#SEPARATOR}
   let rest=$sepLength-$msgLength-1-5
   if [[ $rest < 0 ]]; then
      rest=0
   fi

   # "" verhindert expand der Namen:
   echo "${SEPARATOR:0:4} $* ${SEPARATOR:0:$rest}"

   # Hier wird der Name schon expandiert: verloren....
   echo ${SEPARATOR:0:4} $* ${SEPARATOR:0:$rest}
}

touch eins1
touch eins2

f=("eins*" "zwei*" "drei*")

i=0
# print string        '==== eins* ==============================================='
# ausgabe ist aber '==== eins1 eins2 ==========================================='
m=`colorate "\${f[$i]}"`

# Hier passiert es noch einmal: Name expandiert, verloren...
echo $m

# Wenn jetzt noch die Ausgabe aus "" colorate kommt passt es:
echo "$m"

# print string '==== eins1 eins2 ==========================================='
# ausgabe ist auch '==== eins1 eins2 ==========================================='
m=`colorate ${f[$i]}`

Haveaniceday
 
OP
framp

framp

Moderator
Teammitglied
Thx robi. set -f bzw set +f an der entsprechenden Stelle eingesetzt hat mein Problem gelöst :thumbs:
 
Oben