• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Wir haben den Frühjahrsputz beendet, Ihr auch? Welches Foto zu dem Thema hat Euch dann am Besten gefallen? Hier geht es lang zur Abstimmung --> 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