Hmm, wygląda na to, że dałoby się łatwo zmodyfikować skrypt tak, aby ubijał również proces winedevice.
Jak na mój gust wystarczy zmodyfikować linie: 19 oraz 27:
Dokładnie tak samo na “czuja” próbowałem. Są 2 procesy o takiej nazwie i skrypt uwala tylko jeden z nich.
Edit:
Zapuściłem to teraz z konsoli i wyszło coś ciekawego.
Skrypt pokazuje procesy, które ubijał (a przynajmniej próbował) i jest wśród nich ten, który nie dał się ubić (w tym przypadku, ten “niezatapialny” to był proces 10021):
Sprawdziłem teraz u siebie z pinballem - chyba z WindowsaXP… i u mnie niezmodyfikowany skrypt zabija wszystkie procesy, czyli działa dobrze i skutecznie.
Nazwa winedevice.exe sugeruje, że chodzi o urządzenie. Jeżeli hardware’owe, to może @majo masz coś podłączone, z zabiciem czego system ma problem. Jeżeli software’owe, to … może masz dwa prefix’y (dwie instancje, wersje) wine. A może masz coś uruchomione na root’cie, co blokuje.
Korzystam z wine-staging i pulpitu wirtualnego. Być może to generuje drugi proces C:\windows\system32\winedevice.exe .
Dwa procesy o takiej nazwie uruchamiane są w momencie uruchomienia wine i niezależnie od tego, ile programów działa pod wine.
Po zamknięciu wszystkich programów w wine w normalny sposób, oba te procesy znikają.
Tak to wygląda, przy uruchomionej jednej aplikacji pod wine:
Jeśli chodzi wine, to wszystko zależy od tego, do czego jest potrzebne. Ja akurat koniecznie potrzebuję wirtualny pulpit pod wine, a na W10 mi nie zależy, więc wine-staging mi pasuje.
Natomiast eksperymentując z komendą killall, znalazłem sekwencję, która dla większości przetestowanych programów uruchomionych pod wine (z wyjątkiem jednego programu) zabija wszystkie procesy pod wine: killall -I -w -r .exe
Nie wszystkie procesy, należące do programów pracujących pod wine, mają tekst “wine” w nazwie, więc taka komenda nie zawsze zabije wszystkie procesy z wine.
Po kolejnych testach proponuję złożoną komendę (koniecznie w takiej kolejności) killall -I -w -r .exe && killall -I -w -r wine
Jednak trzeba pamiętać, że przy ubijaniu procesów wine za pomocą killall lub skryptu KillWine, istnieje pewne niebezpieczeństwo przypadkowego ubicia jakiegoś procesu linuksowego, nie pracującego pod wine, który posiada w swojej nazwie tekst “.exe”, “wine” lub inny użyty w skrypcie KillWine.
Za pomocą kombinacji z killall istnieje prawdopodobieństwo ubicia innego procesu. Skrypt z pierwszego postu nie ubije żadnego przypadkowego procesu, ponieważ dokładnie sprawdza wg wzorca wyszukiwania:
wine(64)?-preloader|wineserver
Z moich testów - ograniczonych co prawda do kilku programów pod wine, wynika, że skrypt działa znakomicie.
Nie zdarzyło mi się jeszcze, aby pozostawił jakiś proces.
U mnie akurat, jak wcześniej pisałem, skrypt zostawia jeden proces, ale to drobnostka, którą można poprawić z poziomu menadżera zadań.
Natomiast (chyba?) skrypt KillWine będzie bezpieczniejszy i nie powinien usunąć np. działającego procesu twine, podczas gdy killall go na pewno usunie.
Komenda killall -r wine* usunie tylko procesy z nazwą rozpoczynającą się od tekstu “wine”.
Nie usunie natomiast procesów z tekstem “wine” w środku nazwy procesu, które pozostaną nietknięte. Przykład:
Aby skutecznie usunąć wszelkie procesy z tekstem “wine”, w dowolnym miejscu nazwy i pisane dowolną literą, należałoby zastosować komendę killall -I -w -r wine
Drążąc dalej temat, znalazłem rozwiązanie do bezpiecznego usunięcia absolutnie wszystkich procesów z “wine”, które bazuje na założeniu, że w linuksie nie ma procesów z tekstem “.exe” w nazwie, innych niż te używane przez wine (co chyba jest prawdą).
Zatem najpierw należałoby usunąć wszystko z “.exe” w nazwie za pomocą killall -I -w -r .exe , a następnie skorzystać z bezpiecznego kodu skryptu zamieszczonego w 1. poście do usunięcia pozostałych procesów wine.
Całość wyglądałaby tak:
#!/bin/bash
wine_cellar="${HOME}/.wine"
if (($#)); then
if [[ -e "${wine_cellar}/$1" ]]; then
WINEPREFIX="${wine_cellar}/$1"
shift
elif [[ "${1:0:1}" != "-" ]]; then
echo "ERROR: Didn't understand argument '$1'?" >&2;
exit 1
fi
fi
killall -I -w -r .exe
if ((${#WINEPREFIX})); then
pids=$(
grep -l "WINEPREFIX=${WINEPREFIX}$" $(
ls -l /proc/*/exe 2>/dev/null |
grep -E 'wine(64)?-preloader|wineserver' |
perl -pe 's;^.*/proc/(\d+)/exe.*$;/proc/$1/environ;g;'
) 2> /dev/null |
perl -pe 's;^/proc/(\d+)/environ.*$;$1;g;'
)
else
pids=$(
ls -l /proc/*/exe 2>/dev/null |
grep -E 'wine(64)?-preloader|wineserver' |
perl -pe 's;^.*/proc/(\d+)/exe.*$;$1;g;'
)
fi
if ((${#pids})); then
set -x
kill $* $pids
fi
A tak w ogóle, to w jakim celu ta operacja ma być przeprowadzana? Po, to aby wyczyścić system ze zbędnych procesów wine; zabicie wiszących procesów, aby ponownie uruchomić wine; czy coś innego?
A może zastopowanie server’a wine lub restart - czy, to nie rozwiązuje problemu?
Skrypt może być pomocny przy testowaniu programów pod wine, np. takich, które źle działają np. nie ma okna programu a proces sobie gdzieś zostaje i działa. Dawniej jak częściej próbowałem coś robić z wine, takie sytuacje u mnie się zdarzały.