Bash / xdotool: Befehle funktionieren, aber nicht in einem Skript

4578
Fruckubus Crunt

Ich mache ein Bash-Skript für Linux, das das Terminalfenster schließt, wenn das Fenster den Fokus verliert.

In der Kommandozeile konnte ich folgendes machen:

termwin=$(xdotool getactivewindow)  while :  do  if [[ $(xdotool getactivewindow) != $termwin ]] then  exit  fi  done 

Es funktioniert manuell in ein Terminal eingegeben, aber wenn ich es in ein Skript stecke, stoppt das Skript nicht, sondern schließt das Fenster, wenn der Fokus verloren geht. Kein Fehler oder irgendetwas, einfach zurück zu einer Aufforderung.

Ich habe das Gefühl, dass mir etwas grundlegendes fehlt.

BEARBEITEN

Nach dem Lesen ...: Siehe hier

Ich habe versucht, dies als ". Test.sh" statt als "./test.sh" auszuführen, und es hat funktioniert. Der Link beschreibt den Unterschied zwischen diesen Methoden, wenn das Skript als Unterprozess bzw. als Teil des Hauptprozesses ausgeführt wird. Kann irgendjemand dies einfach erklären und / oder das Skript so ändern, dass es erfolgreich mit "./" anstelle von "." Ausgeführt wird, und letztere Probleme verursacht?

2
Shell-Skript-Debugging ist mein Spaß, halt, ich werde versuchen zu reproduzieren. Ich weiß, dass xdotool ein automatisiertes Werkzeug ist. Rony vor 12 Jahren 0
Meine Idee ist etwas abseits: Wissen Sie von "exotischen" Fenstermanagern? ZB fantastisch (http://awesome.naquadah.org/) - Sie können diese oder ähnliche Funktionen problemlos ausführen. uzsolt vor 12 Jahren 0
@uzsolt, bist du zu? Wenn ich, ich bin hauptsächlich auf ehrfürchtige wm ziemlich einige Jahre und jetzt und alle. Rony vor 12 Jahren 0
Ja :) In Awesome ist das nur etwa 3 Zeilen :) In Bash ... uzsolt vor 12 Jahren 0
@uzsolt Liebe, super Wm hat Lua, Homebrew Widgets sind Süßigkeiten :), Bashlets ist ein weiterer Spielplatz :) Rony vor 12 Jahren 0
Bitte siehe Bearbeiten. Fruckubus Crunt vor 12 Jahren 0
Funktioniert `./test.sh && exit` für Sie? Einfach "exit" oder "exit 0", wenn die Bedingung im Skript erfüllt ist, und "exit" wird danach im Terminal ausgeführt. Daniel Andersson vor 12 Jahren 0
Oh verdammt noch mal, genau das musste ich tun. Ich war zu sehr mit dem Skript beschäftigt, um es in Betracht zu ziehen. Fruckubus Crunt vor 12 Jahren 0
Skripting ist irgendwie wie das Bauen von Teilen gemäß der Nix-Philosophie. xdotool ist so nützlich. Übrigens, hug @ uzolt Rony vor 12 Jahren 0
@uzsolt 2 Zeilen jetzt;) Prost. Rony vor 12 Jahren 0
@Rony, wenn Sie die Teile von "while" berechnen, werden es ungefähr fünf Zeilen sein. In awesome: Sie rufen eine Signalfunktion zum Unscharfstellen auf, rufen "c: kill ()" auf, geben "end" ein und das ist alles. Es sind drei Zeilen. Und du solltest kein Plus-Bash-Skript ausführen, das deine CPU frisst :) So großartig ist der Gewinner;) uzsolt vor 12 Jahren 0

2 Antworten auf die Frage

1
Daniel Andersson

When you source the file with ., the commands will run just as if you had entered them in the command line. Thus exit will exit your currently running shell.

To exit the shell from which the script was executed when forking, you need to get the process id of the parent process. You can try running

kill $ 

in the script instead of exit to kill the parent shell (tip: try just echoing the pid first and check which process it corresponds to so you don't kill your WM or something).

If $ doesn't do it for you, you can also try sending the pid as a parameter to the script, but it depends on how and where it's called.


You said you used urxtvd/urxvtc. With that combination, this script kills the terminal from which it was started:

#!/bin/sh echo kill in 3 sleep 3 kill -1 $ 

so you should be able to use kill -1 in this way to kill a single urxvtc instance.

Note that if you run this by sourcing, then the urxvtd instance will be $PPID for the currently running terminal, and all terminals will die. You don't want that.

Dan, die Kill-PPID-Methode sieht gut aus, schlägt jedoch mit meinem speziellen Terminal fehl. Ich benutze urxvt in einem Client / Daemon-Setup (urxvtd und urxvtc). Es scheint, dass jedes Terminal in diesem Fall die gleiche PPID hat und diese Methode nicht funktioniert. Was anders ist, ist der pty, wie er mit dem Befehl tty gefunden wurde. Sie können einem Pty direkt sagen, etwas zu tun, richtig? So etwas (funktioniert nicht) "exit >> / dev / pts / 0" Fruckubus Crunt vor 12 Jahren 0
@FruckubusCrunt: Jeder _terminal_ hat dieselbe "PPID" (_parent_pid), aber wenn Sie ein _script_ von einem Terminal aus starten, wird die startende _terminal_sid innerhalb des Skripts "PPID" sein, also sendet es das Signal an die richtige pid. Allerdings scheint '-1' bei `urxvtc` erforderlich zu sein. Ich werde meine Antwort aktualisieren. Daniel Andersson vor 12 Jahren 0
Das ist großartig Dan, danke. Eine gute Lernerfahrung für mich. Und ich konnte sicherlich keine Situation akzeptieren, in der mehr Terminals sterben würden, da dies den Zweck meines Tuns zunichte machen würde. Vielen Dank für die solide Erklärung. Fruckubus Crunt vor 12 Jahren 0
0
Rony

Ich hoffe, das Skript funktioniert nach Bedarf:

#!/bin/sh  termwin=$(xdotool getactivewindow) while : ; do [ $(xdotool getwindowfocus) = $termwin ] || kill -9 $PPID done 
Dies liefert die sme-Ergebnisse für mich, es funktioniert, wenn es manuell eingegeben wird, und schlägt fehl Fruckubus Crunt vor 12 Jahren 0
Ich frage mich jetzt, ob "Exit" das Problem ist. In ein Terminal eingegeben, schließt 'exit' das Terminal, aber ist es möglich, dass "exit" in einem Skript eine andere Bedeutung hat, wodurch das Skript angehalten wird, anstatt das Terminal zu schließen? Oder ist das überhaupt möglich? Fruckubus Crunt vor 12 Jahren 0
Bitte siehe Bearbeiten. Fruckubus Crunt vor 12 Jahren 0
[Keine Verwendung von "kill -9"] (http://partmaps.org/era/unix/award.html#uuk9letter). Ein einziger "Kill" ist genug und viel schöner. `kill -9` macht nichts Gutes. Daniel Andersson vor 12 Jahren 0
@DanielAndersson Vielen Dank für Ihre Erfrischung und den sehr nützlichen Link. Ich benutze die -9, weil mein Kill nicht tötet. Ich werde die Angelegenheit prüfen. Rony vor 12 Jahren 0