1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Problem mit do_shell_script

Dieses Thema im Forum "Unix & Terminal" wurde erstellt von interpreter, 02.07.08.

  1. interpreter

    Dabei seit:
    22.02.06
    Beiträge:
    36
    Hi,

    bin mir nicht sicher ob es in Applescript Unterforum oder hierein gehört, evtl. verbirgt sich die Lösung im shellskript, welches ich an do_shell_script übergebe.
    Ich möchte mir eine Liste mit allen Verzeichnissen (rekursiv) ausgeben lassen die mehr als eine Datei bestimmten Typs (hier: *.fid) beinhalten. Dazu habe ich mir im /tmp ein paar Unterordner angelegt und Dateien getoucht. Folgende Ordner enthalten mehr als eine Datei *.fid:
    Code:
    /tmp//foo
    /tmp//foo/bar
    /tmp//foo 1 # <-- ordner mit leerzeichen zum test
    
    Als shell script habe ich folgenden Einzeiler:
    Code:
    find "/tmp/" -type d | (while read a;do [ `ls -p1 "$a" | grep ".fid$" | wc -l` -gt 1 ] && echo "$a";done)
    Ins Applescript habe ich es folgendermassen gepackt:
    Code:
    set the_shell_cmd to ("find \"/tmp/\" -type d | (while read a;do [ `ls -p1 \"$a\" | grep \".fid$\" | wc -l` -gt 1 ] && echo \"$a\";done)") --as string
    log the_shell_cmd
    try
         set posix_file_string to do shell script the_shell_cmd
      on error err
        log "ERROR:" & err 
    end try
    Als Ausgabe im Event-Protokoll bekomme ich:
    Code:
        (*find "/tmp/" -type d | (while read a;do [ `ls -p1 "$a" | grep ".fid$" | wc -l` -gt 1 ] && echo "$a";done)*)
    tell current application
        do shell script "find \"/tmp/\" -type d | (while read a;do [ `ls -p1 \"$a\" | grep \".fid$\" | wc -l` -gt 1 ] && echo \"$a\";done)"
    (*ERROR:/tmp//foo
    /tmp//foo/bar
    /tmp//foo 1*)
    end tell
    
    Da ich den shell-String vorher logge scheinen die Quotes korrekt zu sein, woher resultiert der Fehler?
     
  2. pepi

    pepi Cellini

    Dabei seit:
    03.09.05
    Beiträge:
    8.741
    Aus Neugierde: Warum willst/mußt Du das über ein AppleScript tun/aufrufen? Pack die Zeile einfach in ein eigenes Shellskript und ruf das auf. Hat den Vorteil, daß Du Dich nicht mit zwölffachem Quoting erhängen mußt, und einfacher mal was im ShellCode ändern kannst.


    Die Sektion mit
    enthält ein unnötiges Pipe und ein unnötiges grep.

    Könntest Du in dem Fall auch als ls -1 "$a/*.fid" lösen.

    Und wenn Du statt find "/tmp/" ein find "/tmp" verwendest bekommst auch keine uneleganten // in den Pfaden (die allerdings keinem was tun).

    Wahrscheinlich ließe sich das ganze Problem auch mit einem find | sort | grep (Pseudocode) lösen. Je nachdem was Du mit der Liste dann vor hast.
    Gruß Pepi
     
  3. interpreter

    Dabei seit:
    22.02.06
    Beiträge:
    36
    Das ShellSkript soll tatsächlich aus dem Applescript aufgerufen werden (Die Suche per find ist schneller als den Finder anzusprechen). Ich hatte es auch schon mal probiert das Fragment auszulagern, bekam aber ähnliche Fehler. Ich vermute fast das was mit dem Shellskript faul ist (Funkt da evtl. ein Exit code rein?)
    Problem daran ist das es durchaus Ordner gibt die keine *.fid enthalten, in dem Falle antwortet ls mit
    ls: /tmp/*.fid: No such file or directory

    Wenn ich den abschliessenden / weglasse wird nichts gefunden, deshalb hatte ich ihn erstmal dringelassen.
     
  4. Rastafari

    Rastafari Golden Noble

    Dabei seit:
    10.03.05
    Beiträge:
    17.898
    Schlank ist chic:
    Code:
    find [COLOR="DarkGreen"]"Absoluter_Pfad"[/COLOR]/ -type f -iname "*.[COLOR="DarkGreen"]suffix[/COLOR]" -exec dirname {} \; | sort | uniq -d ;
    Das ganze sollte dann als AppleScript-gerechtes Quoting so aussehen
    (kann ich grade nicht testen, weil an einem XP sitzend):
    Code:
    do shell script "find \"[COLOR="DarkGreen"]Pfad[/COLOR]\"/ -type f -iname \"*.[COLOR="DarkGreen"]suffix[/COLOR]\" -exec dirname {} \\;|sort|uniq -d;"
    Für die Brackets und die Pipes übernehme ich jetzt mal keine Garantie, ich nutze AppleScript nicht gerade besonders oft. Könnte sein, dass du da nachbessern darfst, weiss ich jetzt nicht so genau...

    Hint: Wenn Symlinks ebenfalls als Treffer gefragt sind, darfst du das
    -type f ergänzen zu einem \( -type f -o -type l \)
    Die Backslashes wären dann aber auch noch mal zu maskieren, denn die werden noch gebraucht um die Klammern vor der Shell zu verstecken. Also im AS-Kontext: \\( -type f -o -type l \\)

    Weil /tmp ein Symlink ist und kein Ordner. Der abschliessende Backslash erzwingt eine Auflösung desselben, geht natürlich auch mit der entprechenden Befehlszeilenoption zu find
    --> man find
     

Diese Seite empfehlen