staging.inyokaproject.org

naulilus script will nicht wie ich will... :(

Status: Gelöst | Ubuntu-Version: Ubuntu 19.10 (Eoan Ermine)
Antworten |

DocMcFly

Anmeldungsdatum:
3. Januar 2009

Beiträge: Zähle...

Hallo zusammen,

irgendwas mach ich falsch... und langsam gehen mir die Ideen aus. Hab hier ein Naulilus-Skript (darum werden auch alle echos in eine Datei umgeleitet.) Das Skript (siehe Anhang) soll die selektierten Bilder verkleinern und in eine Mail packen. Hat bei Thunderbird funktioniert, aber bei xdg-email bekomme ich es nicht hin.

Hier ist der spannende Teil des Skriptes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
x=`echo "/usr/bin/xdg-email $uriList"`
echo "x:" >> ~/Bilder/test.log
echo $x >> ~/Bilder/test.log

echo "uriList:" >> ~/Bilder/test.log
echo $uriList  >> ~/Bilder/test.log

echo "execute x:" >> ~/Bilder/test.log
$x >> ~/Bilder/test.log 2>> ~/Bilder/test.log

echo "execute xdg-email:" >> ~/Bilder/test.log
/usr/bin/xdg-email --attach '/tmp/image_to_mail_1581775376/home/clemens/Bilder/x.png'  >> ~/Bilder/test.log 2>> ~/Bilder/test.log

Es wird nur ein neues E-Mail-Fenster geöffnet und das enthält x.png.

im Log-File steht folgendes:

x:
/usr/bin/xdg-email --attach '/tmp/image_to_mail_1581775420/home/clemens/Bilder/y.png' 
uriList:
--attach '/tmp/image_to_mail_1581775420/home/clemens/Bilder/y.png' 
execute x:
/home/clemens/.local/share/nautilus/scripts/ImageToMail.sh: Zeile 81: /usr/bin/xdg-email --attach '/tmp/image_to_mail_1581775420/home/clemens/Bilder/y.png' : Datei oder Verzeichnis nicht gefunden
execute xdg-email:

(evolution-alarm-notify:22170): GLib-GIO-WARNING **: 15:03:41.770: Your application did not unregister from D-Bus before destruction. Consider using g_application_run().

(evolution:22162): GLib-GIO-WARNING **: 15:03:49.227: Your application did not unregister from D-Bus before destruction. Consider using g_application_run().

Was mach ich falsch? Warum kann $x nicht ausgeführt werden? Wenn ich das Echo von $x ins Terminal kopiere und ausführe, dann klappt es.

Hat einer von euch eine Idee?

Danke für eure Hilfe... Clemens

ImageToMail.sh (2.9 KiB)
naulilus script
Download ImageToMail.sh

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Du kannst Dir auf jeden Fall das Leben leichter machen, indem Du die ganzen Umleitungen rausnimmst und da, ab wo Du ausgeben willst, nur ein Mal folgendes schreibst:

1
exec > ~/Bilder/test.log 2>&1

Wenn Du dann auch noch alle Kommandos ausgeben willst, die ausgeführt werden, dann schreibst Du einfach hinter die Zeile mit exec folgendes:

1
set -x

Für die Lesbarkeit ist es auch gut, wenn man konsequent $(...) anstatt der Backticks nimmt. Die Einrückung ist auch nicht konsistent.

Dann fällt auf, dass Du in Zeile 12 vom ersten Block eine Datei "x.png" benennst, aber im Log steht "y.png". Irgendwas passt da nicht zusammen.

Du benutzt für $uriList kein Array. Du hast doch sowieso schon eine bash, dann solltest Du auch ein Array nutzen.

DocMcFly schrieb:

Es wird nur ein neues E-Mail-Fenster geöffnet und das enthält x.png.

man xdg-email sagt:

       xdg-email opens the user's preferred e-mail composer in order to send a mail to address(es) or mailto-uri.
       RFC2368 defines mailto: URIs. xdg-email limits support to, cc, subject and body fields in mailto-uri, all
       other fields are silently ignored.  address(es) must follow the syntax of RFC822. Multiple addresses may be
       provided as separate arguments.

       All information provided on the command line is used to prefill corresponding fields in the user's e-mail
       composer. The user will have the opportunity to change any of this information before actually sending the
       e-mail.

       xdg-email is for use inside a desktop session only. It is not recommended to use xdg-email as root.

Also, alles passiert so, wie es dokumentiert ist.

DocMcFly

(Themenstarter)

Anmeldungsdatum:
3. Januar 2009

Beiträge: Zähle...

Moin,

viele Dank. Du hast mir sehr geholfen. Kurz vorne weg: Die zwei Kommandos "set -x" und "exec > ~/Bilder/test.log 2>&1" sind echt Gold wert ☺ Die kannte ich noch nicht.

Vielleicht hab ich mich falsch ausgedrückt: Mein Beispiel hätte zwei Fenster öffnen sollen. Im "spannenden Teil" Zeile 9:

1
$x >> ~/Bilder/test.log 2>> ~/Bilder/test.log

hätte meiner Meinung nach ein E-Mail-Fenster mit dem Bild y.png geöffnet werden sollen und zur Kontrolle hatte ich noch die Zeile 12 eingebaut. Diese hatte einen statischen Aufruf des E-Mail-Fensters mit dem Bild x.png.

Ich war nun verwirrt, dass nur ein E-Mail-Fenster (mit dem dem x.png-Bild) geöffnet wird. Also der statische Aufruf.

Dank Deines super "set -x"-Befehls kann ich nun sehe, warum ich $x nicht ausführen kann. Die Hochkommas sind gequoted.

Denn jetzt steht in meinem Log:

+ echo 'execute x:'
execute x:
+ '/usr/bin/xdg-email --attach '\''/tmp/image_to_mail_1581839783/home/clemens/Bilder/Bildschirmfoto von 2019-09-11 19-55-41.png'\'' '
/home/clemens/.local/share/nautilus/scripts/ImageToMail.sh: Zeile 84: /usr/bin/xdg-email --attach '/tmp/image_to_mail_1581839783/home/clemens/Bilder/Bildschirmfoto von 2019-09-11 19-55-41.png' : Datei oder Verzeichnis nicht gefunden
execute xdg-email:
+ /usr/bin/xdg-email --attach /tmp/image_to_mail_1581775376/home/clemens/Bilder/x.png

Jetzt hab ich nur eine Frage: Wenn ich $x mit echo ausgebe, dann sehe ich genau den Output, den ich ausführen will. Aber ich kann scheinbar nicht stumpf $x ausführen. Denn die darin enthaltenen Hochkommas sind mit ''' codiert und so entsteht ein ungültiger Dateipfad.

Meine bescheidene Frage... wie löse ich das Problem?

Noch mal um Hilfe... Danke im Voraus Clemens

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

DocMcFly schrieb:

Jetzt hab ich nur eine Frage: Wenn ich $x mit echo ausgebe, dann sehe ich genau den Output, den ich ausführen will. Aber ich kann scheinbar nicht stumpf $x ausführen. Denn die darin enthaltenen Hochkommas sind mit ''' codiert und so entsteht ein ungültiger Dateipfad.

Meine bescheidene Frage... wie löse ich das Problem?

Noch mal um Hilfe...

Ich habe mal ein wenig getestet und der Ansatz funktioniert nicht, den Du da verfolgst:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ var="args.sh 'foo bar'"
$ echo "$var"
args.sh 'foo bar'
$ $var
arg count: 2
arg[1]: ''foo'
arg[2]: 'bar''
$ "$var"
args.sh 'foo bar': command not found
$ eval "$var"
arg count: 1
arg[1]: 'foo bar'
$ echo "$var" | sh
arg count: 1
arg[1]: 'foo bar'

Die Lösung findest Du in Zeile 10 oder 13. Da Du aber eine bash nutzt, würde ich ein Array verwenden - dann kann man eval vermeiden:

1
2
3
4
5
6
$ var=(args.sh 'foo bar')
$ echo "${var[*]}"
args.sh foo bar
$ "${var[@]}"
arg count: 1
arg[1]: 'foo bar'

args.sh gibt einfach nur die Argumente aus. Das Skript steht auf meiner Profilseite.

DocMcFly

(Themenstarter)

Anmeldungsdatum:
3. Januar 2009

Beiträge: 196

Hallo,

Danke für Deine Hilfe. aber sorry ich raff es nicht.

Ich fasse mal kurz zusammen wie ich die Funktion meines Skriptes sehe und Du kannst mir dann sagen wo ich falsch liege:

  1. Ich bekommen von Nautilus eine Variable ($NAUTILUS_SCRIPT_SELECTED_URIS) mit lauter URIs.

  2. diese sind mit einem Leerzeichen getrennt. Also kann ich diese Behandeln wie ein Array. Darum kann ich diese in einer for-Schleife durchlaufen. (die URIs an sich enthalten auch keine Leerzeichen diese sind HTML-codiert.)

  3. dann erzeuge ich die Bilder in der gewünschten Auflösung

  4. ABER ich brauche für xdg-email keine URIs sondern lokale Pfade. Diese können auch Leerzeichen enthalten. Darum ist die Array-Codierung mit Leerzeichen als Trennzeichen Asche.

  5. Unter php-cli hätte ich jetzt einfach geschrieben $myArray[] = $cuted. Ein Äquivalent in bash habe ich nicht gefudnen. Darum habe ich

    1
    uris=$uris$convertBaseDir$cuted$'\n';; 
    

    geschrieben.

    1
    $'\n'
    

    ist dann das Trennsymbol.

  6. mittels:

1
2
3
4
IFS=$'\n'
for uri in $uris; do
    uriList=$uriList$"--attach '"$uri"' "
done

schneide ich das auseinander und packe das "--attach" und die Hochkommas dazu.

Wenn ich dann noch das xdg-email davor schreibe, sollte ich es haben... aber dieses total intuitive Bashing 😉 (nichts gegen Dich - Deine Hilfe ist super) macht mir plötzlich aus einem

" ' "

das hier

'\' '

← häää?

(wo ich immer dachte, das

"'"

bedeutet: ich will da ein einfaches Hochkomma drin haben, denn nur ein einzelnes Hochkomma kann man ja da nicht in diesem Kontext schreiben...

Wie gesagt ich raff es nicht... Alle Beispiele die ich von Arrays gefunden habe, sind immer sehr statisch. Ich will aber mein Array aus eines anderen Array konvertieren. Und die Syntax von der bash ist echt unterirdisch.

Ich würde ja gerne es vermeiden auf php-cli umzusteigen, aber aktuell sehe ich das als einzigen Ausweg... und darum bin ich hier um das zu vermeiden.

Verstehst Du mein Dilemma?

Gruß Clemens

DocMcFly

(Themenstarter)

Anmeldungsdatum:
3. Januar 2009

Beiträge: 196

Sooo... nach dem ich meine Gedanken durch meinen letzten Post sortiert habe und noch etwas mit den Skript etwas rumgespielt habe ich nun eine funktionierende Lösung:

Danke für eure Hilfe... Ich werde wohl nie ein Freund von der Bash...

Grüße Clemens

 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/bash

urldecode(){
  echo -e "$(sed 's/+/ /g; s/%/\\x/g; s/file:\/\///')" 
}

mode=$( zenity --list --radiolist  --title "Dateien senden..." --hide-column=2 \
     --column "Auswahl" --column "mode" --column "Bildgröße" \
      false  "320"  "Mini (max. 320px)" \
      false "640"  "Klein (max. 640px)" \
      true "800"  "Mittel (max. 800px)" \
      false "1024" "Groß (max. 1024px)" \ 
      false "2048" "Größer (max. 2048px)" ) 


# prepare
lines=`echo $NAUTILUS_SCRIPT_SELECTED_URIS |wc -w`
part=`expr 98 / $lines`
count="0"

(
	echo "0"  
	convertBaseDir=/tmp/image_to_mail_`date +'%s'`
	for uri in $NAUTILUS_SCRIPT_SELECTED_URIS; do
		# echo $uri 
		if [[ $uri == file://* ]]
			then 
				cuted=`echo "$uri" | urldecode`
				# echo "minie" 
				#echo $cuted 
				mime=`file -b --mime-type "$cuted"`
				case "$mime" in
					"image/jpeg"|"image/png"|"image/tiff")
						# echo $(identify -format "%w %h" $cuted)
						# echo "minie" 
						imageHeight=$(identify -format "%h" "$cuted")
						imageWidth=$(identify -format "%w" "$cuted")
						if [ "$imageWidth" -ge "$mode" ] || [ "$imageHeight" -ge "$mode" ]
						then 
							geometry=" -geometry ${mode}x${mode}"
						else
							geometry=""
						fi
						 # echo $geometry
							convertDir=$convertBaseDir`dirname "$cuted"`
							mkdir -p "$convertDir"
							convert -auto-orient $geometry "$cuted" "$convertBaseDir$cuted"
							#echo $(identify -format "%w %h" $convertBaseDir$cuted)
							uris=$uris"$convertBaseDir$cuted"$'\n';;
				 *) uris=$uris"$cuted"$'\n';;
				esac
			else 
				cuted=`echo "$uri" | urldecode`
				uris=$uris$cuted$'\n'
		fi
		count=`expr $count + $part`
		echo $count 
	done

	IFS=$'\n'
	for uri in $uris; do
			uriList=$uriList' --attach '"'$uri'"
	done

	#	exec > ~/Bilder/test.log 2>&1
	#	set -x

	x=`echo "/usr/bin/xdg-email $uriList"`
	eval $x

	echo "100"
)| zenity --progress --title="Bilder werden angepasst..." --percentage=0 --auto-close 


exit 0

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

DocMcFly schrieb:

Ich fasse mal kurz zusammen wie ich die Funktion meines Skriptes sehe und Du kannst mir dann sagen wo ich falsch liege:

Ja, soweit alles klar.

  1. Ich bekommen von Nautilus eine Variable ($NAUTILUS_SCRIPT_SELECTED_URIS) mit lauter URIs.

  2. diese sind mit einem Leerzeichen getrennt. Also kann ich diese Behandeln wie ein Array. Darum kann ich diese in einer for-Schleife durchlaufen. (die URIs an sich enthalten auch keine Leerzeichen diese sind HTML-codiert.)

  3. dann erzeuge ich die Bilder in der gewünschten Auflösung

  4. ABER ich brauche für xdg-email keine URIs sondern lokale Pfade. Diese können auch Leerzeichen enthalten. Darum ist die Array-Codierung mit Leerzeichen als Trennzeichen Asche.

  5. Unter php-cli hätte ich jetzt einfach geschrieben $myArray[] = $cuted. Ein Äquivalent in bash habe ich nicht gefudnen.

Lies Dir mal die Manpage der bash zu Arrays durch oder bei uns im Wiki: Shell/Bash-Skripting-Guide für Anfänger (Abschnitt „Arrays“)

Hier nur ein Beispiel. Das ist kaputt, weil schon $uris kein Array ist. Du müsstest also $uris schon als Array benutzen (also Zeilen 52, 53 und 57 des ursprünglichen Skriptes).

1
2
3
4
5
6
7
8
9
uriList=()

for uri in $uris; do
    uriList+=(--attach "$uri")
done

...

/usr/bin/xdg-email "${uriList[@]}"

Wichtig ist hier, dass Du die Array-Variable mit Double Quotes einschließt und "@" innerhalb der eckigen Klammern verwendest. Wenn $uris auch ein Array ist, sieht der Code von oben so aus:

1
2
3
4
5
6
7
8
9
uriList=()

for uri in "${uris[@]}"; do
    uriList+=(--attach "$uri")
done

...

/usr/bin/xdg-email "${uriList[@]}"

So funktioniert es auch mit Leerzeichen in Dateinamen. Übrigens kannst Du Dir eins von den beiden Arrays sparen - Du kannst ja gleich beim Befüllen von $uris immer ein "--attach" mit einfügen. Das ist auch effizienter, weil Du Dir einen Durchlauf sparst.

Darum habe ich

1
uris=$uris$convertBaseDir$cuted$'\n';; 

geschrieben.

1
$'\n'

ist dann das Trennsymbol.

Das hilft Dir aber nicht, weil Du bei der weiteren Verarbeitung

  1. mittels:

1
2
3
4
IFS=$'\n'
for uri in $uris; do
    uriList=$uriList$"--attach '"$uri"' "
done

schneide ich das auseinander und packe das "--attach" und die Hochkommas dazu.

Ja, aber das ist alles überflüssig und fehlerträchtig (z.B. geht die Lösung kaputt mit Dateinamen, die ein "'" enthalten) - man sollte einfach Arrays richtig verwenden.

Wenn ich dann noch das xdg-email davor schreibe, sollte ich es haben... aber dieses total intuitive Bashing 😉 (nichts gegen Dich - Deine Hilfe ist super) macht mir plötzlich aus einem

" ' "

das hier

'\' '

← häää?

Wie gesagt, da brauchst Du dann eval.

Wie gesagt ich raff es nicht... Alle Beispiele die ich von Arrays gefunden habe, sind immer sehr statisch.

Das wäre aber sehr merkwürdig. Elemente zu Arrays hinzuzufügen ist doch gerade eine Grundfunktionalität.

Ich will aber mein Array aus eines anderen Array konvertieren. Und die Syntax von der bash ist echt unterirdisch.

Gewöhnungsbedürftig, ja. Mich hat es am Anfang auch etwas gekostet, bis ich das mit dem Quoting so gerafft habe, dass ich Skripte schreiben konnte, die mit ungewöhnlichen Zeichen in Dateinamen korrekt umgehen können. Habe mal ein modifiziertes aber ungetestetes Skript angehängt.

9135408-ImageToMail-rklm.sh (2.7 KiB)
modifizierte Version des ursprünglichen Skriptes
Download 9135408-ImageToMail-rklm.sh

DocMcFly

(Themenstarter)

Anmeldungsdatum:
3. Januar 2009

Beiträge: 196

Vielen herzlichen Dank für Deine Hilfe, Deine Geduld und Deinen Hinweis auf die bash-Arrays.

Besonders hilfreich war Dein Beispiel-Coding. Dort stand etwas, was ich in den Array-Dokumentationen so nicht gefunden hab:

1
myArray+=(neuer Wert)

In ganz vielen Beschreibungen des Bash-Arrays wurde das Array einmal angelegt und dann wieder ausgegeben. Erst das "+=" hat mir richtig geholfen. Als ich das in Deinem Post sah, dachte ich mir: ahhh so einfach kann es manchmal sein ☺

Nach dem ich mein Skript auf ein Array umgestellt hab, kann ich mir auch das eval sparen ☺ Auch hierfür Danke.

Ich hab viel gelernt. Im Anhang habe ich die letzte Version meines Skripts hinzugefügt. Falls es jemand brauchen kann.

Anleitung: Damit kann man in Nautilus Bilder oder andere Dateien markierten und an eine Gnome Evolution Mail anhängen. Vorher kann man sich aussuchen, ob man die Bilder noch verkleinern lassen möchte. Finde ich sehr praktisch bei den heutigen großen DSLR-Bildern. ☺ Installation: Kopiere das Skript nach ~/.local/share/nautilus/scripts/ . Du brauchst dafür gnome zenity (für den Dialog und die Progressbar) und graphics magick (für Bildkonvertierung) .

Ein schönes Wochenende wünscht Clemens

ImageToMail.sh (1.9 KiB)
Download ImageToMail.sh
Antworten |