You are not logged in.

#1 2012-11-24 13:00:52

rix
Member
Registered: 2012-07-25
Posts: 238

[Bash] A simple explanation by you about an already working lil'script

Hi archers,
since I'd like to learn, I've to ask you an explanation about my .xinitrc.

I've achieved this through testing:

#!/usr/bin/env bash
# $HOME/.xinitrc

"${HB}"/stApp.sh
"${DWM}"/statBar.sh

while : ; do
    dwmLog="${DWM}/dwm.log"    
    
    exec dbus-launch dwm 2> "${dwmLog}" & dwmPid="${!}"
    wait "${dwmPid}"
done

Which works as aspected but I can't understand why:
1) If the wm runs as first, statBar.sh doesn't load.
2) For the purpose to be able to reload Dwm without closing X, I use the "while loop". But if I don't save Dwm's pid it'll be closed with X. Why?

Thanks a lot.

Last edited by rix (2012-11-24 13:13:03)

Offline

#2 2012-11-24 15:25:03

stqn
Member
Registered: 2010-03-19
Posts: 1,191
Website

Re: [Bash] A simple explanation by you about an already working lil'script

It might work if you remove “exec”.

Offline

#3 2012-11-24 15:30:26

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

Tested and works even this way.
Do you mind explain me why?
And what about the second question?
Thanks a lot.

Last edited by rix (2012-11-24 15:36:52)

Offline

#4 2012-11-24 15:58:17

oeufcoque
Member
Registered: 2012-11-09
Posts: 19
Website

Re: [Bash] A simple explanation by you about an already working lil'script

rix wrote:

Hi archers,
2) For the purpose to be able to reload Dwm without closing X, I use the "while loop". But if I don't save Dwm's pid it'll be closed with X. Why?

`exec' runs a command without creating a new process. Instead it replaces the current process.

When `exec' exits, which happens when dwm exits, it will also exit the .xinitrc script.

When you put a `&' you run exec in the background, giving it a new process. This way the .xinitrc script doesn't exit as its process isn't being replaced. This is why it works for you.

To try it, do like this:
1. Open a terminal
2. Type `bash'
3. Type `exit'
4. You'll see you returned to the original terminal, since it was still running

1. Open a terminal
2. Type `exec bash'
3. Type `exit'
4. Now you see it took the original terminal down with it, since that process was replaced with exec

Offline

#5 2012-11-24 16:06:20

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

oeufcoque wrote:

[...] To try it, do like this: [...]

How cool. Thank so much. I've learnt something new. smile

So without "exec" and "&", we're working on the Dwm process which is under the .xinitrc one. Is it right?
So when we close Dwm, we don't close .xinitrc (and X) which restart Dwm. Isn't it?

Offline

#6 2012-11-24 16:12:52

oeufcoque
Member
Registered: 2012-11-09
Posts: 19
Website

Re: [Bash] A simple explanation by you about an already working lil'script

rix wrote:
oeufcoque wrote:

[...] To try it, do like this: [...]

How cool. Thank so much. I've learnt something new. smile

So without "exec" and "&", we're working on the Dwm process which is under the .xinitrc one. Is it right?
So when we close Dwm, we don't close .xinitrc (and X) which restart Dwm. Isn't it?

True.

In your case I would simply discard "exec" and do something like:

#!/usr/bin/env bash
# $HOME/.xinitrc

"${HB}"/stApp.sh
"${DWM}"/statBar.sh

while : ; do
    dwmLog="${DWM}/dwm.log"    
    
    dbus-launch dwm 2> "${dwmLog}"
done

edit: I'm not sure how dbus-launch works exactly though

Last edited by oeufcoque (2012-11-24 16:14:06)

Offline

#7 2012-11-24 16:16:16

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

Also as stqn above has suggested and obviously works.
Many thanks again. smile

Do you mind tell me also, if you can, why if I run first the wm instead of the statusbar script, this last one doesn't load?

Last edited by rix (2012-11-24 16:17:21)

Offline

#8 2012-11-24 19:56:48

oeufcoque
Member
Registered: 2012-11-09
Posts: 19
Website

Re: [Bash] A simple explanation by you about an already working lil'script

rix wrote:

Also as stqn above has suggested and obviously works.
Many thanks again. smile

Do you mind tell me also, if you can, why if I run first the wm instead of the statusbar script, this last one doesn't load?

It depends on what your statusbar script does. But I see it is not started in the background, so maybe that's the problem.

Add "&" after statusbar script might solve it.

Usually you write your .xinitc like this:

# Commands and programs to start in the background once when X starts
command-to-run-in-the-background &
statusbar &
terminal &
pidgin &

# Window manager in this loop will restart itself when it exit, unless it crashes
while true ; do
  dwm || exit 1
done

You can also write it like this, but then it will not restart itself. This is how my .xinitrc looks. Maybe it will give inspiration.

exec wmfs &
PID=$!

# Keyboard shortcuts
xbindkeys &

# Copy/paste stuff
autocutsel -fork &
autocutsel -selection PRIMARY -fork &

# Mouse pointer speed
xset m 0 0

# Wallpaper
feh --bg-scale $HOME/.wall.png &

# Terminal daemon so it starts faster and uses less memory
urxvtd -o -f &

# Statusbar script
wmfs.sh &

# Popup messages
dunst &

# Popup messages daemon script
dunstd.sh &

# Snow on my screen
xsnow -sc "#787878" -nowind -notrees -nosanta -norudolf &

# Mount devices automatically and start ranger
devmon --exec-on-drive "urxvtc -e sh -c \"ranger %d\"" &

wait $PID

Offline

#9 2012-11-24 20:04:40

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

I'm sorry my fault. I forgot to post the statusbar.
Here it is:

#!/usr/bin/env sh
while :
    do
	    clk() {
            hr=$(date +"%R")
            echo -e "\x01$hr"
        }
	    dt() {
            dt=$(date +"%a %d")
            echo -e "\x07 $dt "
        }
        net() {
            ping -c 1 www.google.it > /dev/null || echo -e "\x02 NC"
        }
        vol() {
            st=$(amixer get Master | awk '{print $6}' | tr -d '[]' | tail -1)
            lv=$(amixer get Master | awk '{print $4}' | tr -d '[]','%' | tail -1)
            [ "${st}" != "off" ] && echo -e "\x05 $lv"
        }
        mail() {
            f="$HOME/.fetchmailoutput"
            h=$(cat ${f} | awk '/hotmail/ {print +$1}')
            g=$(cat ${f} | awk '/gmail/ {print +$1}')
            if [[ "${h}" -ge "1" && "${g}" -ge "1" ]]; then
                echo -e "\x03 H:${h} G:${g}"
            fi
            if [[ "${h}" -ge "1" && "${g}" -eq "fetchmail" ]]; then
                echo -e "\x03 H:${h}"
            fi
            if [[ "${g}" -ge "1" && "${h}" -eq "fetchmail" ]]; then
                echo -e "\x03 G:${g}"
            fi
        }
       	up() {
	        count=$(pacman -Qu | wc -l)
	        [ "${count}" -eq "0" ] || echo -e "\x04 $count"
	    }
        ram() {
            ram=$(free -m | awk '/-/ {print +$3}')
	        [ "${ram}" -gt "200" ] && echo -e " \x06R:$ram"
	    }
        cTemper() {
            sens=$(sensors | awk '/temp1/ {print +$2}')
	        [ "${sens}" -gt "75" ] && echo -e "\x06C:$sens"
	    }
        
        out="$(cTemper)$(ram)$(up)$(mail)$(net)$(vol)$(dt)$(clk)"
        xsetroot -name "$out"
        sleep 1s
done &

Also why is it needing to save wm process' pid?

Thank a lot for your helps.

Offline

#10 2012-11-24 20:41:40

oeufcoque
Member
Registered: 2012-11-09
Posts: 19
Website

Re: [Bash] A simple explanation by you about an already working lil'script

It's only needed in the .xinitrc I'm using.

Remember, if .xinitrc exit, X will exit too.

That's why I have a "wait" in it, so it will wait until my window manager (wmfs) will exit. If I don't wait for it, then .xinitrc will exit even if I have my window manager running, and that will kill X.

If you use "exec" it looks like .xinitrc is still running, so X won't exit.

You have your window manager inside a "while" loop, so .xinitrc will never exit, and X will always be running.

About your script:
You can change position where it starts in .xinitrc to:

#!/usr/bin/env bash
# $HOME/.xinitrc

"${HB}"/stApp.sh


while : ; do
    dwmLog="${DWM}/dwm.log"

   # start statusbar and remember pid of it
    "${DWM}"/statBar.sh &
    statBarPid=$!

   # Start dbus and window manager. This will continue running until dwm exit or crashes
    dbus-launch dwm 2> "${dwmLog}"

   # Kill statusbar script
    kill $statBarPid
done

Then remove "&" from your statusbar script. It is at last line after "done".

Offline

#11 2012-11-24 21:02:46

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

About statusbar isn't more simple with the "&" in the script instead of saving its pid? What are differences?
By the way, I got it.

Thanks for your patience. smile

Last edited by rix (2012-11-24 21:04:12)

Offline

#12 2012-11-24 21:20:51

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [Bash] A simple explanation by you about an already working lil'script

If you use dbus-launch you'll probably want to use

dbus-launch --exit-with-session dwm

This will ensure dbus exits when the window manager does.  The way you have it now, if you restart dwm many times, you could get many instances of dbus running simultaneously.

In my experiences many dbus instances do not interfere with each other, but they do each use a bit (a small bit) of memory and processor cycles.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#13 2012-11-24 22:24:31

rix
Member
Registered: 2012-07-25
Posts: 238

Re: [Bash] A simple explanation by you about an already working lil'script

Thanks you for your suggestion Trilby.

OT:
@ Trilby:
do you mind, if you can, to also reply to my thread about Dwm?
Thanks.

Offline

Board footer

Powered by FluxBB