Bash / xdotool: команды работают, но не в скрипте

4479
Fruckubus Crunt

Я делаю bash-скрипт для Linux, который закрывает окно терминала, если окно теряет фокус.

В командной строке я смог сделать это:

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

Он работает набранным вручную в терминале, но, если я помещаю его в скрипт, вместо закрытия окна, когда фокус теряется, скрипт просто останавливается. Нет ошибок или чего-то еще, просто вернитесь к подсказке.

Я чувствую, что мне не хватает чего-то простого.

РЕДАКТИРОВАТЬ

Прочитав это ...: смотрите здесь

Я попытался запустить это как ". Test.sh", а не "./test.sh", и это сработало. Ссылка описывает разницу в этих методах как запуск сценария как подпроцесса или как часть основного процесса, соответственно. Может кто-нибудь просто объяснить это и / или изменить сценарий для успешной работы с "./" вместо ".", В последнем случае возникают проблемы?

2
Отладка сценария - это мое удовольствие, держись, я постараюсь воспроизвести. Я знаю, xdotool это инструмент для автоматизации. Rony 11 лет назад 0
Моя идея немного не по теме: знаете ли вы об «экзотических» оконных менеджерах? Например, потрясающе (http://awesome.naquadah.org/) - вы можете легко выполнять эту или аналогичные функции. uzsolt 11 лет назад 0
@uzsolt, ты должен? если я, я в основном на удивительном WM довольно несколько лет, а теперь и все. Rony 11 лет назад 0
Да :) в офигенном это всего около 3 строчек :) в bash ... uzsolt 11 лет назад 0
@uzsolt, дорогой, у wm есть lua, доморощенные виджеты - это конфеты :), bashlets - еще одна игровая площадка :) Rony 11 лет назад 0
Пожалуйста, смотрите редактировать. Fruckubus Crunt 11 лет назад 0
`./Test.sh && exit` работает на вас? Просто `exit` или` exit 0`, когда условие выполняется в сценарии, и впоследствии `exit` будет запущен в терминале. Daniel Andersson 11 лет назад 0
О, черт возьми, это именно то, что я должен был сделать. Я был слишком поглощен самим сценарием, чтобы подумать о его запуске. Fruckubus Crunt 11 лет назад 0
Сценарии как-то похожи на создание частей, как в соответствии с философией nix xdotool так полезен. кстати, обнимаю @ uzolt Rony 11 лет назад 0
@uzsolt 2 строки сейчас;) ура. Rony 11 лет назад 0
@Rony, если вы вычислите части `while`, это будет около пяти строк. Замечательно: вы вызываете функцию сигнала для расфокусировки, вызываете `c: kill ()`, набираете `end` и все. Это три строки. И вы не должны запускать скрипт плюс bash, который съедает ваш процессор :) uzsolt 11 лет назад 0

2 ответа на вопрос

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.

Дэн, метод kill PPID выглядит хорошо, но не работает с моим конкретным терминалом. Я использую urxvt в настройке клиента / демона (urxvtd и urxvtc). Кажется, что каждый терминал в этом случае имеет один и тот же ppid, и s = o, этот метод не работает. Что отличается, так это pty, найденный с помощью команды tty. Вы можете прямо сказать pty что-то сделать, верно? Что-то вроде (не работает) "выход >> / dev / pts / 0" Fruckubus Crunt 11 лет назад 0
@FruckubusCrunt: Каждый _terminal_ имеет одинаковый `PPID` (_parent_ pid), но когда вы запускаете _script_ из терминала, внутри скрипта pid запускающего _terminal_ будет` PPID`, поэтому он отправляет сигнал на правильный pid. Тем не менее, `-1`, по-видимому, необходим для` urxvtc`. Я обновлю свой ответ. Daniel Andersson 11 лет назад 0
Это здорово, Дэн, спасибо. Хороший опыт обучения для меня. И я, конечно, не мог принять ситуацию, когда погибло бы больше терминалов, так как это противоречило бы цели того, что я делаю. Так что спасибо за убедительное объяснение. Fruckubus Crunt 11 лет назад 0
0
Rony

Hope the script will work as needed:

#!/bin/sh termwin=$(xdotool getactivewindow) while : ; do [ $(xdotool getwindowfocus) = $termwin ] || kill -9 $PPID done 
Это дает результаты смэ для меня, он работает, если набрать вручную, и не удается Fruckubus Crunt 11 лет назад 0
Теперь мне интересно, если проблема в «выходе». При вводе в терминал «выход» закрывает терминал, но возможно ли, что «выход» имеет другое значение в сценарии, который останавливает сценарий, а не закрывает терминал? Или это вообще возможно? Fruckubus Crunt 11 лет назад 0
Пожалуйста, смотрите редактировать. Fruckubus Crunt 11 лет назад 0
[Воздерживаться от использования `kill -9`] (http://partmaps.org/era/unix/award.html#uuk9letter). Достаточно одного «убийства» и намного приятнее. `kill -9` ничего хорошего не делает. Daniel Andersson 11 лет назад 0
@DanielAndersson большое спасибо за вашу свежесть и очень полезную ссылку. Я использую -9, потому что мое убийство не убивает. Я посмотрю в этом вопросе. Rony 11 лет назад 0

Похожие вопросы