Kirjoittaja Aihe: dash-skriptin ajo käynnistimestä  (Luettu 3242 kertaa)

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
dash-skriptin ajo käynnistimestä
« : 28.06.21 - klo:16.38 »
Etsin vanhaa ketjua, mutta en ole 100% varma onko se täällä vai jossain muualla. Kyse oli siitä, että kun komentotiedoston ajaa .desktop-käynnistimellä, niin dash-scriptissä ei voi käyttää exit-komentoa mutta bash-scriptissä voi. Jossain siitä on keskusteltu, ja haluaisin löytää selityksen sille miksi dash-scriptiä ei voi keskeyttää exitillä.

Tälle asialle on vaikea keksiä hakusanoja.

nm

  • Käyttäjä
  • Viestejä: 16428
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #1 : 28.06.21 - klo:16.54 »
Kuulostaa oudolta. Pystytkö jakamaan esimerkkiskriptin ja desktop-tiedoston, joilla ongelma ilmenee?

Kokeilin itse tällaisilla tiedostoilla, ja exit toimi ihan hyvin:

~/dashexit.desktop
Koodia: [Valitse]
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Dash Exit Testi
Exec=/usr/local/bin/dashexit.sh
Icon=application.png
Terminal=false

/usr/local/bin/dashexit.sh
Koodia: [Valitse]
#!/bin/sh

while true; do
    date >> ${HOME}/dashexit.log
    echo "Exiting" >> ${HOME}/dashexit.log
    exit 0
done

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #2 : 28.06.21 - klo:17.04 »
Minulla ein nyt taida olla selalista dash-skriptiä käytössä jota asia koskee, kaikki ovat bash-skriptejä. Mutta silloin aikanaan ongelma tuli eteen kun tein skpriptin joka ajaa itsensa sudolla, ja kun palataan aliprosessista takaisin, mimnulla oli exit, mutta skripti jatkoi siitä iloisesti uudestaan siihen osioon jossa tarvittin sudoa. Näin muistelen. Mutta en tiedä voiko mun muistiin enää luottaa. Juju kumminkin oli se että dash-skripti ajetaan sourcettamalla tms. mutta bashiä tämä ei koske. Kyse voi olla myös Unity/Gnome-erosta.

Muistelen jopa että se oli juuri nm joka asian silloin selitti, mutta muisti voi todella tehdä tepposet.

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #3 : 28.06.21 - klo:17.16 »
Jotain tällaista aloin kirjoittaa, mutta sitten aloin hakea slitystä sille miksi mun vanhoissa koodiesimerkeissä on tää ero.

Koodia: [Valitse]
# This script can be run both from cli and from desktop launcher.

gui=false                               # via desktop launcher or command line?
quit=exit                               # graceful exit when $gui is true
case $_shell in
    dash) [ $SHLVL -eq 0 ] && gui=true && quit=return ;;
    bash) [ $SHLVL -eq 1 ] && gui=true ;;
    *)  # TBD
;;
esac

# pause requires Terminal=true in desktop launcher
# (in other words [ -t 0 ] && [ -t 1 ] must be true)
pause () { read -p "$1" ${2:-any} ; }

# run as root logic
if [ "$EUID" -ne 0 ] || $gui            # not root or via desktop launcher?
then
    if [ -t 1 ]                         # terminal?
    then
sudo $0 $@
s=$?
$gui && pause "sulje> "         # stop before closing window
$quit $s                        # graceful exit
    else
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY $0 $@
$quit $?                        # graceful exit
    fi
fi
# $gui is now false and $EUID is 0
#
# for safe exit, call abort only when $gui is false
abort () {
    local s=${2:-$?}                    # cache status
    [ $s -eq 0 ] && $s=1                # force failure
    if [ -t 1 ]
    then
echo "$1"
    else
notify-send -t 10 -u critical -i dialog-error $(basename $0) "$1"
    fi
    exit $s                             # relay status
}
# ... commands to run as root ...

Olen vasta testannut bashin kanssa tuota logiikkaa; idea on muokata  tästä sourcetettava skripti.

nm

  • Käyttäjä
  • Viestejä: 16428
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #4 : 28.06.21 - klo:17.31 »
Okei, saman skriptin ajaminen sudolla skriptin sisällä on melkoisen hasardia purkkaa. :) Vaikea nähdä silmämääräisesti, mitä tuossa oikeastaan tapahtuu shellin kannalta.

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #5 : 28.06.21 - klo:17.57 »
Eihän tuossa pätkässä tapahdu mitään muuta kuin se sudotus, kaikki muu on määrittelyjä.

Okei, täytyy viritellä esimerkkitapaus ja testata dashillä.

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #6 : 28.06.21 - klo:19.27 »
Olen nyt testaillut ja todennus että dash ja bash toimivat exitin suhteen samalla tavalla, toisin kuin muistin.

Tässä koko skripti:

Koodia: [Valitse]
#!/usr/bin/sh
_the_=$_                                # this script, even if sourced
_shell=$(readlink /proc/$$/exe | xargs basename)

# This script is meant to be sourced in a dash/bash script which
# is runnable both via desktop launcher and on command line,
# but also serves as a template for such a script.

# plain notifications without terminal I/O:
self=$(basename $0)
notify  () { notify-send -t 10                               $self "$1" ; }
notifyW () { notify-send -t 10 -u critical -i dialog-warning $self "$1" ; }
notifyE () { notify-send -t 10 -u critical -i dialog-error   $self "$1" ; }

# display error message as notification if terminal is not available:
abort () {
    local s=${2:-$?}
    [ $s -eq 0 ] && $s=1                # force failure
    [ -t 1 ] && echo "$1" || notifyE "$1"
    exit $s
}

# user interface with terminal I/O only:
pause () {
    read -p "$1" ${2:-any}              # requires [ -t 0 ] && [ -t 1 ]
}

# running via desktop launcher or command line?
gui=false
case $_shell in
    dash) [ $SHLVL -eq 0 ] && gui=true ;;
    bash) [ $SHLVL -eq 1 ] && gui=true ;;
    *) abort "$_the_: Päivitä $_shell-tuki." ;;
esac

# optional:

if ${require_terminal:-false}
then
    if [ ! -t 1 ]                           # 0 = stdin, 1 = stdout, 2 = stderr
    then
abort "Set Terminal=true in desktop launcher or run in terminal."
    fi
fi
if ${run_as_root:-false}                   # run as root with sudo or pkexec
then
   if [ "$EUID" -ne 0 ] || $gui            # not root or via desktop launcher?
   then
       if [ -t 1 ]                         # terminal?
       then
   sudo $0 $@
   s=$?                            # cache status
   $gui && pause "sulje> "         # prompt user before closing window
   exit $s
       else
   pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY $0 $@
   exit 1
       fi
   fi
fi
# if $run_as_root true, $gui is now false and $EUID is 0
# ... commands to run as root ...

ja sen voi tosiaan sourcettaa siinä skriptissä jonka käynnistää .desktop -käynnistimellä. Omat skriptit on pitkiä, joten poimin palstalta mahdollisimman lyhyen malliksi ja muunsin sen sourcettamaan tämän yllä olevan:

Koodia: [Valitse]
#!/bin/sh
require_terminal=true
run_as_root=true
. $(dirname $0)/.uirc # ~/bin/.uirc

apt update && apt full-upgrade

Tuo on niin lyhyt, ettei siinä käytetä yhtään funktiota joita on tarjolla, mutta uskoisin että jos joku viitsii kokeilla, niille funktioillekin löytyy käyttöä.

Jouduin tuohon keksimään jonkun nimen skriptilleni että siihen voi viitata, mutta nimen voi valita vapaasti toisinkin.
« Viimeksi muokattu: 28.06.21 - klo:19.38 kirjoittanut AimoE »

AimoE

  • Käyttäjä
  • Viestejä: 2782
    • Profiili
Vs: dash-skriptin ajo käynnistimestä
« Vastaus #7 : 29.06.21 - klo:08.01 »
Minulla olikin dash-skripti, eikä siinä ajeta mitään sudolla, vaan pyöritetään valikkoluuppia, tyyliin:

Koodia: [Valitse]
while true
do
    printf "\n$title:\n$(update_menu)\n\n$question [poistu]: "
    read word
    [ -z "$word" ] && exit # tässä minulla oli return dashin takia
    clear
    # ... käsittele vastaus ...
done

Lisäsin sourcetettavaan skriptiini funktion

Koodia: [Valitse]
_uitest () {
    local io sh="
Running $(readlink /proc/$$/exe)
at SHLVL=$SHLVL"
    [ -t 0 ] && io="$io stdin"
    [ -t 1 ] && io="$io stdout"
    [ -t 2 ] && io="$io stderr"
    [ -n "$io" ] && io="\nwith $io on terminal"
    #notifyE "$_the_: $sh$io."
    echo -e "$_the_: $sh$io." > ~/uirc_$_shell.log
}

ja testasin vielä kerran.

bash:
Koodia: [Valitse]
:
Running /usr/bin/bash
at SHLVL=1
with  stdin stdout stderr on terminal.

dash:
Koodia: [Valitse]
-e /usr/bin/dbus-update-activation-environment:
Running /usr/bin/dash
at SHLVL=0
with  stdin stdout stderr on terminal.

Tästä näkyy selitys sille että return päättää dash-skriptin suorituksen (ja sillekin että $SHLVL ei ole sama). Suoritus toki päättyy exit-komennollakin, mutta jostain syystä olin siinä uskossa että exit on kielletty. Lähdettä sille tiedolle en vaan kertakaikkiaan muista, enkä keksi millä hakusanoilla se löytyisi.