ubuntuusers.de

verschiedene doppelte Anführungszeichen unterschiedliche Wirkung

Status: Gelöst | Ubuntu-Version: Ubuntu 16.04 (Xenial Xerus)
Antworten |

Matten

Anmeldungsdatum:
17. Juli 2007

Beiträge: 23

Wohnort: Lüneburg

Hallo Leute, ich bin heute auf ein Problem gestoßen, dass kann ich mir grad nicht erklären. Ich habe ein Skript aus einem Buch abgetippt (Wicked Cool Shell Scripts, Kapitel 1 Skript inpath). In einer Zeile steht

1
for directory in $ourpath

geschrieben hatte ich jedoch

1
for directory in "$ourpath"

mit meinen doppelten Anführungszeichen funktionierte das Skript jedoch nicht. Mit den doppelten Anführungszeichen (Alt Gr +b / +n) schon.

Abgesehen davon, dass ich bisher nicht einmal wusste, dass man mit Alt Grausam + b/n doppelte Anführungszeichen erzeugen kann, warum haben sie eine andere Wirkung? Bzw. warum funktionieren die normalen doppelten Anführungszeichen (shift + 2) nicht? Bzw. wo liegt der Unterschied zwischen den beiden Zeichen?

Das Skript kann man sich hier https://www.nostarch.com/download/WickedCoolShellScripts2e_resources_updated.zip ansehen. Ist gleich das erste. Es soll im Grunde nur überprüfen, ob ein Programm in den Verzeichnissen der $PATH Variablen enthalten ist. Zum Testen muss am Ende die Auskommentierungen entfernen.

Mit fragenden Grüßen

Matthias

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Irgendwie kommt mir das Shell-Skript insgesamt merkwürdig vor - zum einen gibt es genau für diesen Zweck which und zum anderen führen die Unicode-Anführungszeichen dazu, dass das das Skript für das erste und letzte Element in PATH nie einen Treffer landen kann, weil der Pfad mit vorangestelltem bzw. abschließenden Anführungszeichen nicht im PATH enthalten sein kann (sieht man mit dem in Zeile 17 eingefügten echo) - und da der IFS auf ":" gesetzt ist, braucht es eigentlich keine Anführungszeichen um die Variable $ourpath an der Stelle, um die einzelnen Pfade aus der PATH-Variable zu holen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 #!/bin/bash
 # inpath--Verifies that a specified program is either valid as is
 #   or can be found in the PATH directory list.
 
 in_path()
 {
    # Given a command and the PATH, try to find the command. Returns
    #   0 if found and executable, 1 if not. Note that this temporarily 
    #   modifies the IFS (internal field separator) but restores it 
    #   upon completion.
 
    cmd=$1        ourpath=$2         result=1
    oldIFS=$IFS   IFS=":"
 
    for directory in $ourpath    do
      echo "$directory"
      if [ -x $directory/$cmd ] ; then
        result=0      # if we're here, we found $cmd in $directory
      fi
    done
 
    IFS=$oldIFS
    return $result
  }
 
  checkForCmdInPath()
  {
    var=$1
 
    if [ "$var" != "" ] ; then
      if [ "${var:0:1}" = "/" ] ; then
        if [ ! -x $var ] ; then
          return 1
        fi
      elif !  in_path $var "$PATH" ; then
        return 2
      fi
    fi
 }
 
 if [ $# -ne 1 ] ; then
   echo "Usage: $0 command" >&2 ; exit 1
 fi
 
 checkForCmdInPath "$1"
 case $? in
   0 ) echo "$1 found in PATH"                   ;;
   1 ) echo "$1 not found or not executable"     ;;
   2 ) echo "$1 not found in PATH"               ;;
 esac
 
 exit 0
> $ bash foo.sh which                                       
“/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/lib/jvm/default/bin
/usr/bin/site_perl
/usr/bin/vendor_perl
/usr/bin/core_perl”
which found in PATH 

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

seahawk1986 schrieb:

Irgendwie kommt mir das Shell-Skript insgesamt merkwürdig vor - zum einen gibt es genau für diesen Zweck which

Ich empfehle dringend type zu nehmen - das ist ein Shell-Builtin, das dementsprechend auch Shell-Funktionen und Aliase berücksichtigt. Ansonsten kann die Ausgabe sehr irreführend sein:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ which h
$ type h
h is aliased to `history'
$ which ls
/bin/ls
$ type ls
ls is aliased to `ls --color=auto -F'
$ type -a ls
ls is aliased to `ls --color=auto -F'
ls is /bin/ls
$ type mkcd
mkcd is a function
mkcd () 
{ 
    mkdir "$1" && cd "$1"
}

Matten

(Themenstarter)

Anmeldungsdatum:
17. Juli 2007

Beiträge: 23

Wohnort: Lüneburg

Hallo seahawk1986, die Idee hinter dem Skript ist, festzustellen ob eine Programm sich in einem Pfad der $PATH Variablen oder in einem dem Skrip übergebenen Pfad befindet. Später soll die Funktionalität vermutlich aus anderen Skripten heraus aufgerufen werden, ist zumindest meine Vermutung.

und da der IFS auf ":" gesetzt ist, braucht es eigentlich keine Anführungszeichen um die Variable $ourpath an der Stelle, um die einzelnen Pfade aus der PATH-Variable zu holen:

Irgendwie hast du da recht, ohne Quotes kommen die Pfade alle einzeln rausgepurzelt, so wie es eigentlich sein soll.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  1 #!/bin/bash
  2 oldIFS=$IFS IFS=":"
  3 ourpath=$PATH
  4 
  5 for dir in $ourpath
  6 do
  7         echo "$dir"
  8 done
  9 
 10 IFS=$oldIFS

Anscheinend haben die AltGr+n/b Quotes gar keine Wirkung, sondern sind schlichtweg Zeichen, die mit ausgegeben werden. Villeicht ist es auch einfach einfach Tippfehler gewesen, und weil es zu 80% funktioniert, mit Ausnahme des ersten und letzten Pfads der $PATH-Variablen,ist es wohl gar nicht weiter aufgefallen...

sebix Team-Icon

Ehemalige

Anmeldungsdatum:
14. April 2009

Beiträge: 5584

Matten schrieb:

Anscheinend haben die AltGr+n/b Quotes gar keine Wirkung, sondern sind schlichtweg Zeichen, die mit ausgegeben werden. Villeicht ist es auch einfach einfach Tippfehler gewesen, und weil es zu 80% funktioniert, mit Ausnahme des ersten und letzten Pfads der $PATH-Variablen,ist es wohl gar nicht weiter aufgefallen...

Diese Unicode-Anfuehrungszeichen haben jedenfalls keine spezielle Funktion, sondern sind schlicht die Zeichen, die sie sind (und zu Fehlern fuehren).

Matten

(Themenstarter)

Anmeldungsdatum:
17. Juli 2007

Beiträge: 23

Wohnort: Lüneburg

Hallo sebix

Diese Unicode-Anfuehrungszeichen haben jedenfalls keine spezielle Funktion, sondern sind schlicht die Zeichen, die sie sind (und zu Fehlern fuehren).

dann bin ich ja erleichtert. Hab schon an mir gezweifelt 😉

Danke euch allen

Gruß

Matthias

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Ja .... das Skript ist ja wirklich gruselig !

Nicht nur diese verkehrten „Quotes” (die es in der Shell gar nicht gibt), sondern gleich noch mehr:
2 Zeilen darüber steht oldIFS=$IFS (unge"quotet" !!) - wehe, wenn Du das ausführst, dann ist $IFS hinterher garantiert kaputt.
(und so geht das ja wohl weiter ...)

Also ist die ganze Geschichte einfach nur ein "never-ever-do-it-like-them !" , ein warnendes Beispiel.

Orientier Dich besser an vernünftigen Projekten wie z.B. unserem Wiki.
Die sind auch nicht perfekt, aber immerhin haben wir solche gravierenden Fehler dort mit vereinten Kräften ausgemerzt.

Oder an Greg's Wiki - das ist richtig gut. (da gucke ich selber als alter Hase noch regelmäßig rein !)

LG, und viel Erfolg,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Und, wie gesagt, es gibt das Kommando type. Das steht sogar im POSIX-Standard...

Antworten |