Коомпьютер с linux при выключении не спрашивает разрешения на выключение у приложний, так как алгоритм выключения был придуман для консольного режима работы, когда все работающие приложения были демонами (аналог резидентов в DOS), которые нежалко убивать. В настоящее время, компьютер работает с оконными приложениями, которых, в момент нажатия на кнопку завершения работы, выполняется около десятка, причем в каждом из которых могут быть результаты многочасового труда пользователя компьютера. Но команда выключения linux этого не понимает и все их закрывает не посылая им никаких сообщений и недавая пользователю возможможности передумать. В результате все введенные тексты и нарисованные картинки, схемы, чертежи будут потерены безвозвратно.
То есть процесс завершения работы linux реализован хуже, чем было сделано в windows 3.1, вероятно даже 1.0. В windows при выключении компьютера окнам посылается куча сообщений с запросом завершения работы: WM_QUERYENDSESSION (запрос разрешения выключения), WM_ENDSESSION (иформирование об выключении), WM_CLOSE (запрос разрешения закрытия окна)..... В результате самая тупая программа понимает, что надо сохраняться. Все завершается корректно.
В стабильнейшемем gdk после десятков лет работы нет аналога WM_QUERYENDSESSION, а в описании GDK_DELETE, аналоге WM_CLOSE , не сказано, что оно посылается при выключении компьютера, а только при нажии на специальную кнопку на заголовке.
Самое любопытное, пользователей linux это нисколько не волнует. Я для решения этой проблемы придумал деревянный костыль, который надо поместить в автозагрузку и запускать от root. Делается это через sudo, visudo, sudoers.
Скрипт для перезагрузки.
Скрипт для выключения.
Это костыль, так как проблему он до конца не решает: он не умеет посылать сообщения окнам свернутым в трей.
То есть процесс завершения работы linux реализован хуже, чем было сделано в windows 3.1, вероятно даже 1.0. В windows при выключении компьютера окнам посылается куча сообщений с запросом завершения работы: WM_QUERYENDSESSION (запрос разрешения выключения), WM_ENDSESSION (иформирование об выключении), WM_CLOSE (запрос разрешения закрытия окна)..... В результате самая тупая программа понимает, что надо сохраняться. Все завершается корректно.
В стабильнейшемем gdk после десятков лет работы нет аналога WM_QUERYENDSESSION, а в описании GDK_DELETE, аналоге WM_CLOSE , не сказано, что оно посылается при выключении компьютера, а только при нажии на специальную кнопку на заголовке.
the window manager has requested that the toplevel window be hidden or destroyed, usually when the user clicks on a special icon in the title bar.
Самое любопытное, пользователей linux это нисколько не волнует. Я для решения этой проблемы придумал деревянный костыль, который надо поместить в автозагрузку и запускать от root. Делается это через sudo, visudo, sudoers.
Скрипт для перезагрузки.
#/bin/sh
export DISPLAY=":0"
ProgName="SwitchOff"
ErrMsg()
{
zenity --error --text "$1" --title "$ProgName"
}
wmvar=$(wmctrl -l) ; if [ $? -ne 0 ] ; then ErrMsg "wmctrl return error" ; exit ; fi
if [ "BAD" = "$(printf "%s" "$wmvar" | sed -nE '/^0[xX][[:xdigit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+.*$/bskip;s/^.*$/BAD/p;:skip')" ]
then ErrMsg "wmctrl return error" ; exit ; fi
wmvar=$(printf %s "$wmvar" | grep -Ev '[[:xdigit:]]+[[:space:]]+-1')
if [ $? -ne 0 ] ; then ErrMsg "grep return error" ; exit ; fi
ListWID=$(printf %s "$wmvar" | sed -nE '/^[[:xdigit:]]+/s/^([[:xdigit:]xX]+).*$/\1/p')
if [ $? -ne 0 ] ; then ErrMsg "sed return error" ; exit ; fi
for wid in $ListWID
do
wmctrl -i -c $wid
#echo ""
done
i=600
NumWndOld=10000
( while [ $i -ne 0 ]
do
sleep 0.1s ; if [ $? -ne 0 ] ; then ErrMsg "sleep return error" ; exit ; fi
i=$(($i-1)) ; echo $((100-$i/6))
wmvar=$(wmctrl -l 2>&1) ; if [ $? -ne 0 ] ; then continue ; fi
if [ "BAD" = "$(printf "%s" "$wmvar" | sed -nE '/^0[xX][[:xdigit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+.*$/bskip;s/^.*$/BAD/p;:skip')" ]
then continue ; fi
wmvar=$(printf %s "$wmvar" | grep -Ev '[[:xdigit:]]+[[:space:]]+-1' |\
grep -Ev "[[:xdigit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+$ProgName")
if [ "$wmvar" = "" ] ; then shutdown -r now ; exit ; fi
NumWnd=$(printf %s "$wmvar" | wc -l) ; if [ $? -ne 0 ] ; then ErrMsg "wc return error" ; exit ; fi
NumWnd=$(($NumWnd+1)) ; if [ $? -ne 0 ] ; then ErrMsg "calc expr return error" ; exit ; fi
echo "# Waiting close of $NumWnd windows."
if [ $NumWnd -ne $NumWndOld ] ; then wmctrl -i -a $(printf %s "$wmvar" | sed -nE '1s/^([[:xdigit:]xX]+).*$/\1/p') ; fi
NumWndOld=$NumWnd
done
) | zenity --progress --title="$ProgName" --text="waiting..." --percentage=0 --auto-close || exit
Скрипт для выключения.
#/bin/sh
export DISPLAY=":0"
ProgName="SwitchOff"
ErrMsg()
{
zenity --error --text "$1" --title "$ProgName"
}
wmvar=$(wmctrl -l) ; if [ $? -ne 0 ] ; then ErrMsg "wmctrl return error" ; exit ; fi
if [ "BAD" = "$(printf "%s" "$wmvar" | sed -nE '/^0[xX][[:xdigit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+.*$/bskip;s/^.*$/BAD/p;:skip')" ]
then ErrMsg "wmctrl return error" ; exit ; fi
wmvar=$(printf %s "$wmvar" | grep -Ev '[[:xdigit:]]+[[:space:]]+-1')
if [ $? -ne 0 ] ; then ErrMsg "grep return error" ; exit ; fi
ListWID=$(printf %s "$wmvar" | sed -nE '/^[[:xdigit:]]+/s/^([[:xdigit:]xX]+).*$/\1/p')
if [ $? -ne 0 ] ; then ErrMsg "sed return error" ; exit ; fi
for wid in $ListWID
do
wmctrl -i -c $wid
#echo ""
done
i=600
NumWndOld=10000
( while [ $i -ne 0 ]
do
sleep 0.1s ; if [ $? -ne 0 ] ; then ErrMsg "sleep return error" ; exit ; fi
i=$(($i-1)) ; echo $((100-$i/6))
wmvar=$(wmctrl -l 2>&1) ; if [ $? -ne 0 ] ; then continue ; fi
if [ "BAD" = "$(printf "%s" "$wmvar" | sed -nE '/^0[xX][[:xdigit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+.*$/bskip;s/^.*$/BAD/p;:skip')" ]
then continue ; fi
wmvar=$(printf %s "$wmvar" | grep -Ev '[[:xdigit:]]+[[:space:]]+-1' |\
grep -Ev "[[:xdigit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+$ProgName")
if [ "$wmvar" = "" ] ; then shutdown -h now ; exit ; fi
NumWnd=$(printf %s "$wmvar" | wc -l) ; if [ $? -ne 0 ] ; then ErrMsg "wc return error" ; exit ; fi
NumWnd=$(($NumWnd+1)) ; if [ $? -ne 0 ] ; then ErrMsg "calc expr return error" ; exit ; fi
echo "# Waiting close of $NumWnd windows."
if [ $NumWnd -ne $NumWndOld ] ; then wmctrl -i -a $(printf %s "$wmvar" | sed -nE '1s/^([[:xdigit:]xX]+).*$/\1/p') ; fi
NumWndOld=$NumWnd
done
) | zenity --progress --title="$ProgName" --text="waiting..." --percentage=0 --auto-close || exit
Это костыль, так как проблему он до конца не решает: он не умеет посылать сообщения окнам свернутым в трей.
no subject
Date: 2017-08-01 02:54 am (UTC)Суть вашей претензии - "почему Линукс не Виндоуз ?"
Потому что нет необходимости.
При желании же можно применить отложенный shutdown
shutdown -s -t 3600
Можно тупо сделать составную команду
sleep 300; shutdown now
- она даже лучше читается
Кстати, без now сразу не выключает, видимо по умолчанию таймаут есть.
Можно привязать ее к кнопке выключения на рабочем столе или в меню.
Можно добавить проверку условий, например запущенных пользователем программ.
Этого в Линуксе не нет, но мало востребовано, поэтому и разговоров нет.
no subject
Date: 2017-08-01 12:50 pm (UTC)ну это уже наглость.
большинство северов в в мире работают на линукс.
них работают базы данных и веб сервера.
базы данных работают - и обысно они запущены как демоны.
no subject
Date: 2017-08-02 12:51 am (UTC)no subject
Date: 2017-08-02 01:22 am (UTC)внес в документ информацию и не сохраняя ее выключил перезагрузил (через меню).
либр офис у меня ничего не просил при выключении!
однако после загрузки, открыл офис - а внесенная информацию есть.
no subject
Date: 2017-08-02 12:06 pm (UTC)Я снял "скринкаст" процесса перезагрузки с открытым офисом, в котором был несохраненный текст. На нем все видно.
no subject
Date: 2017-08-02 01:25 pm (UTC)с полной процедурой загрузки.