• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

Problem mit do_shell_script

Registriert
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?
 

pepi

Cellini
Registriert
03.09.05
Beiträge
8.740
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
ls -p1 "$a" | grep ".fid$"
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
 
Registriert
22.02.06
Beiträge
36
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.

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?)
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.
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

Und wenn Du statt find "/tmp/" ein find "/tmp" verwendest bekommst auch keine uneleganten // in den Pfaden (die allerdings keinem was tun).
Wenn ich den abschliessenden / weglasse wird nichts gefunden, deshalb hatte ich ihn erstmal dringelassen.
 

Rastafari

deaktivierter Benutzer
Registriert
10.03.05
Beiträge
18.150
Ich möchte mir eine Liste mit allen Verzeichnissen (rekursiv) ausgeben lassen die mehr als eine Datei bestimmten Typs (hier: *.fid) beinhalten.
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 \\)

Wenn ich den abschliessenden / weglasse wird nichts gefunden, deshalb hatte ich ihn erstmal dringelassen.
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