| View previous topic :: View next topic |
| Author |
Message |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Thu Apr 26, 2012 9:43 pm Post subject: Yet another on-lid-close acpi action (for e17, tty, ...) |
|
|
I've written an acpi script for the lid open/close event.
When the lid is closed, it waits for 3 seconds and exits without action if the lid has been opened again.
If the lid stayed close the script locks the screen and - on ac-power - blanks it or - on battery-power - suspends to ram.
Unlike other scripts I found here or elsewhere on the net it does not need 'xhost +local:0', as this is considered to be insecure.
It locks the screen of enlightenment sessions but can be configured to work with kde-4/kde-3/gnome/xscreensaver/xdg-screensaver.
To use it put a file with the following content into /etc/acpi/events/:
| Code: | event=button[ /]lid
action=/etc/acpi/actions/my_lid.sh %e |
Save the script below to /etc/acpi/actions/my_lid.sh and make it executable.
| Code: | #! /bin/sh
# lid button pressed/released event handler
# default display on current host
DISPLAY=":0.0"
# time in seconds to wait after lid has been closed
TIMEOUT="3"
# your username FIXME: Is there a dynamic way to get a current X user?
XUSER="lars"
##
# your screen lock command:
# enlightenment)
SCREEN_LOCK='enlightenment_remote -desktop-lock'
# or
#SCREEN_LOCK="dbus-send --print-reply=literal --dest=org.enlightenment.wm.service /org/enlightenment/wm/RemoteObject org.enlightenment.wm.Desktop.Lock"
# kde-4)
#SCREEN_LOCK='qdbus org.freedesktop.ScreenSaver /ScreenSaver Lock'
# kde-3)
#SCREEN_LOCK='dcop kdesktop KScreensaverIface lock'
# gnome)
#SCREEN_LOCK='gnome-screensaver-command --lock'
# xscreensaver)
#SCREEN_LOCK='xscreensaver-command -lock'
# xdg-screensaver)
#SCREEN_LOCK='xdg-screensaver lock'
# to syslog
log (){
logger -t lid-action -- "$@"
}
xsu () {
if [[ -z "$DBUS_SESSION_BUS_ADDRESS" ]]; then
# Looks like we are outside X
home=$(grep $XUSER /etc/passwd)
home=${home#*:*:*:*:*:}
home=${home%:*}
log "home is: $home"
# Get the latest file in session-bus directory
dbus_file=$(ls $home/.dbus/session-bus/ -t | head -1)
log "dbus file is: $dbus_file"
# and export a variable from it
log "source $home/.dbus/session-bus/$dbus_file"
. "$home/.dbus/session-bus/$dbus_file" && export DBUS_SESSION_BUS_ADDRESS
fi
log "dbus session address is: $DBUS_SESSION_BUS_ADDRESS"
log "su -l -c \"DISPLAY=$DISPLAY $@\" $XUSER"
ERROR=$( { su -l -c "DISPLAY=$DISPLAY $@" $XUSER; } 2>&1 )
log "$ERROR"
}
# pass the command you want to execute on lid close to this function
execute_command () {
# this script only cares for LID close events
if [ "$close" == "close" ]
then
## now sleep for a while and then check if the user decided
## to open the lid again
#
#acpi_listen -t $TIMEOUT
# the above won't work since this script blocks acpid
# so acpi_listen would not report any events while this
# script is executed
sleep $TIMEOUT
STATUS=$(</proc/acpi/button/lid/LID/state)
if [ "${STATUS##* }" == "open" ]
then
log "on-lid-close-action interrupted"
else
# lock screen
log "locking screen"
xsu "$SCREEN_LOCK"
# take action
log "$@"
"$@"
fi
fi
}
log "$@"
# close or open?
close=$3
# check if we are on ac- or on battery-power
on_ac_power
if [ $? -ne 0 ]
then
# BATTERY
log "on battery power"
# suspend to ram
execute_command pm-suspend
else
# AC
log "on AC power"
# switch-off screen
execute_command xsu "xset -display $DISPLAY dpms force off"
fi |
As I am not an experienced shell scripter you may help my by making suggestions for improvements.
I am not sure if the ways to bypass X-server and dbus access restrictions are secure?
And I wonder if there is a dynamic way to find the current user of the X-screen? _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
ppurka Advocate

Joined: 26 Dec 2004 Posts: 3067
|
Posted: Fri Apr 27, 2012 1:02 am Post subject: |
|
|
I use this to get the XUSER dynamically:
| Code: | | X_USER="$(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p")" |
_________________ emerge --quiet redefined | E17 vids: I, II |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Fri Apr 27, 2012 7:48 am Post subject: |
|
|
| ppurka wrote: | I use this to get the XUSER dynamically:
| Code: | | X_USER="$(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p")" |
|
I tried using who but I noticed it only reports users logged into a shell. This would work for me, because I have always at least one terminal open (yakuake) but if you have just an X session open, who does not report the user (at least not here with lxde-base/lxdm and e17.
Does it work with other Display Managers? _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
ppurka Advocate

Joined: 26 Dec 2004 Posts: 3067
|
Posted: Fri Apr 27, 2012 8:36 am Post subject: |
|
|
It depends on whether your login manager registers the user in the utmp/wtmp file. I use slim and I think it does that. I do remember that there were some broken login managers which did not do this. This was 2y ago, when I was looking for a decent, lightweight login manager. _________________ emerge --quiet redefined | E17 vids: I, II |
|
| Back to top |
|
 |
M Guru

Joined: 12 Dec 2006 Posts: 427
|
Posted: Fri Apr 27, 2012 1:26 pm Post subject: |
|
|
Hi, your script looks nice. I will try it, I use something much simpler right now.
You can maybe get XUSER by looking at xinit user, something like this:
| Code: | | XUSER=$(ps aux | grep [x]init | awk '{print $1}') |
This works for me, I use qingy in text mode as login manager, I believe this will work also with startx, don't know how other login managers work but I think they do start xinit?
Also, small addition to SCREEN_LOCK would be slock from suckless project, very simple screen locker. I would add also a variable for suspend command. I never had to use pm-utils, plain "echo 3 > /proc/acpi/sleep" or "echo -n mem > /sys/power/state" always worked for me.
Cheers,
M |
|
| Back to top |
|
 |
tclover Apprentice

Joined: 10 Apr 2011 Posts: 295
|
Posted: Sun Apr 29, 2012 6:26 pm Post subject: |
|
|
@ppurka:
the simpliest, leanest login manager is:
| ~/.zlogin: | # $Id: ~/.zlogin, 2012/04/29 -tclover Exp $
# auto startx depending on the tty
if [[ -z $DISPLAY ]] && [[ $EUID != 0 ]] { startx &> ~/.xsession-errors & }
# start gnome-keyring
if [[ -n $DISPLAY ]] && [[ -z $GNOME_KEYRING_PID ]] {
eval $(gnome-keyring-daemon)
export GNOME_KEYRING_PID
export GNOME_KEYRING_SOCKET
export SSH_AUTH_SOCK
export GPG_AGENT_INFO
}
# vim:fenc=utf-8:ci:pi:sts=0:sw=4:ts=4 |
or (for bash users)
| ~/.bash_login: | # $Id: ~/.bash_login, 2012/04/29 -tclover Exp $
# auto startx depending on the tty
[[ -z $DISPLAY ]] [[ $UID != 0 ]] && startx &> ~/.xsession-errors &
# start gnome-keyring
[[ -n $DISPLAY ]] && [[ -z $GNOME_KEYRING_PID ]] && {
eval $(gnome-keyring-daemon)
export GNOME_KEYRING_PID
export GNOME_KEYRING_SOCKET
export SSH_AUTH_SOCK
export GPG_AGENT_INFO
}
# vim:fenc=utf-8:ci:pi:sts=0:sw=4:ts=4: |
and...
| ~/.xinitrc: | # $Id: ~/.xinitrc, 2012/04/29 -tclover Exp $
eval $(gnome-keyring-daemon)
export GNOME_KEYRING_PID
export GNOME_KEYRING_SOCKET
export SSH_AUTH_SOCK
export GPG_AGENT_INFO
dbus-launch nm-applet --sm-disable &
dbus-launch gcm-session &
#xcalib -gc 1.0 -b 0.0 -co 100.0 .icc/sRGB_v4_ICC_preference.icc
laditray &> /dev/null &
/usr/libexec/polkit-gnome-authentication-agent-1 &
unclutter -idle 8 -noevents &
[ -e ~/.Xmodmap ] && xmodmap ~/.Xmodmap
xset s off
xset fp+ /usr/share/fonts/TTF-FD/
xset fp+ /usr/share/fonts/artwiz-latin1
xset fp+ /usr/share/fonts/artwiz-aleczapka-en
xset fp+ /usr/share/fonts/terminus
xset fp rehash
#xrdb -merge ~/.Xdefaults
#xrdb -merge ~/.xcolors/sj-bright
xrdb -load ~/.Xresources
/usr/bin/urxvtd -q -o -f &
case $(tty | cut -b6-) in
tty1) exec ck-launch-session dbus-launch --sh-syntax --exit-with-session enlightenment_start.sh;;
tty2) exec ck-launch-session dbus-launch --sh-syntax --exit-with-session lxsession ;;
tty3) exec ck-launch-session dbus-launch --sh-syntax --exit-with-session openbox-session ;;
esac
# vim:fenc=utf-8:ci:pi:sts=0:sw=4:ts=4: |
nothing else is more efficient than that. Extra ~/.zlogout or ~/.bash_logout are available on https://github.com/tokiclover/dotfiles/.
@M: this should work
[code]XUSER=$(ps aux | grep xinit | awk '{print $1}' | head -n1)
I'll try that script when I have some time... I was looking for one but I was lazy enough to not write one myself. _________________ mkinitramfs-ll:topic 879125::(bar-)overlay:topic 889918 |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Mon Apr 30, 2012 8:25 am Post subject: |
|
|
| ppurka wrote: | | It depends on whether your login manager registers the user in the utmp/wtmp file. I use slim and I think it does that. |
Yes, indeed your method to get the X user dynamically works with slim and presumably other "non-broken" login managers.
I switched to slim. How did you configure it to start e17?
I put a small script into /etc/X11/Sessions/
/etc/X11/Sessions/e17:
| Code: | #!/bin/sh
/usr/bin/enlightenment_start |
and told slim in /etc/slim.conf to read from Session directory:
| Code: | | sessiondir /etc/X11/Sessions |
| M wrote: | You can maybe get XUSER by looking at xinit user, something like this:
| Code: | | XUSER=$(ps aux | grep [x]init | awk '{print $1}') |
|
On my machine this returns nothing.
| tclover wrote: | @M: this should work
| Code: | | XUSER=$(ps aux | grep xinit | awk '{print $1}' | head -n1) |
|
On my machine this returns my user name if I call it as my user, and "root" if it is called by root. As the script is executed by root this would not work.
@M,tclover
Nice to hear that you want to try the script! Please tell me if it works on your machine - up to know it only passed the womm certificate program
@all:
I'm about to add your suggestions, I will post the script as soon as its finished. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
ppurka Advocate

Joined: 26 Dec 2004 Posts: 3067
|
Posted: Mon Apr 30, 2012 2:58 pm Post subject: |
|
|
Great! Good to know you find it (the code and slim, both) useful
My configuration for slim is identical to what you have done. The only difference (IMHO, not noteworthy) is that I mentioned the sessions as
| Code: | | sessions enlightenment,Xsession | and I have both those files in /etc/X11/Sessions _________________ emerge --quiet redefined | E17 vids: I, II |
|
| Back to top |
|
 |
dmpogo Advocate

Joined: 02 Sep 2004 Posts: 2166 Location: Canada
|
Posted: Tue May 01, 2012 3:07 am Post subject: |
|
|
What I do on lid close is both suspend to ram and write hibernate image, so that if I forget and laptop runs out of battery why suspended to ram,
I have a hibernation image to start from. |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Wed May 09, 2012 9:48 pm Post subject: |
|
|
I added a function which tries several suspend to ram methods as suggested by M and a variable to replace this function by a custom method - for example one that writes a hibernate image as suggested by dmpogo.
For me there is no use for a hibernate image, since my whole hard drive except a small boot partition is encrypted. Even swap is encrypted with a random key. Besides I think the suspend method is out of the scope of this script, but as I said it is easy to add your own suspend script.
I also added slock. Thank you, M for pointing me to the suckless project, which is quite interesting.
Here's the script:
| Code: | #! /bin/sh
# lid button pressed/released event handler
# default display on current host
DISPLAY=":0.0"
# time in seconds to wait after lid has been closed
TIMEOUT="3"
# some broken login managers (e.g. lxdm) do not register the user in the utmp/wtmp file
# if you use such a login manager put your username here
XUSER="lars"
##
# your suspend command
# pm-utils
#SUSPEND="pm-suspend"
# plain echo to /sys or /proc file
SUSPEND="suspend_to_ram"
##
# your screen lock command:
# enlightenment)
SCREEN_LOCK='enlightenment_remote -desktop-lock'
# or
#SCREEN_LOCK="dbus-send --print-reply=literal --dest=org.enlightenment.wm.service /org/enlightenment/wm/RemoteObject org.enlightenment.wm.Desktop.Lock"
# kde-4)
#SCREEN_LOCK='qdbus org.freedesktop.ScreenSaver /ScreenSaver Lock'
# kde-3)
#SCREEN_LOCK='dcop kdesktop KScreensaverIface lock'
# gnome)
#SCREEN_LOCK='gnome-screensaver-command --lock'
# xscreensaver)
#SCREEN_LOCK='xscreensaver-command -lock'
# xdg-screensaver)
#SCREEN_LOCK='xdg-screensaver lock'
# slock)
#SCREEN_LOCK='slock'
# to syslog
log (){
logger -t lid-action -- "$@"
}
# get access to X and dBus session
xsu () {
# get the X user dynamically
xuser="$(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p")"
log "detected X user is: $xuser"
if [[ -z "$xuser" ]]; then
# fallback to static username
xuser=$XUSER
fi
if [[ -z "$DBUS_SESSION_BUS_ADDRESS" ]]; then
# Looks like we are outside X
home=$(grep $xuser /etc/passwd)
home=${home#*:*:*:*:*:}
home=${home%:*}
log "home is: $home"
# Get the latest file in session-bus directory
dbus_file=$(ls $home/.dbus/session-bus/ -t | head -1)
log "dbus file is: $dbus_file"
# and export a variable from it
log "source $home/.dbus/session-bus/$dbus_file"
. "$home/.dbus/session-bus/$dbus_file" && export DBUS_SESSION_BUS_ADDRESS
fi
log "dbus session address is: $DBUS_SESSION_BUS_ADDRESS"
log "su -l -c \"DISPLAY=$DISPLAY $@\" $xuser"
su -l -c "DISPLAY=$DISPLAY $@" $xuser
}
# suspend to ram
suspend_to_ram () {
# look for /sys file
if [[ -e /sys/power/state ]]
then
log "echo -n mem > /sys/power/state"
echo -n mem > /sys/power/state
elif [[ -e /proc/acpi/sleep ]]
then
# try deprecated /proc/acpi file
log "echo 3 > /proc/acpi/sleep"
echo 3 > /proc/acpi/sleep
else
# try to invoke pm-utils
log "pm-suspend"
pm-suspend
fi
}
# pass the command you want to execute on lid close to this function
execute_command () {
# this script only cares for LID close events
if [ "$close" == "close" ]
then
## now sleep for a while and then check if the user decided
## to open the lid again
#
#acpi_listen -t $TIMEOUT
# the above won't work since this script blocks acpid
# so acpi_listen would not report any events while this
# script is executed
sleep $TIMEOUT
STATUS=$(</proc/acpi/button/lid/LID/state)
if [ "${STATUS##* }" == "open" ]
then
log "on-lid-close-action interrupted"
else
# lock screen
log "locking screen"
xsu "$SCREEN_LOCK"
# take action
log "$@"
ERROR=$( { "$@"; } 2>&1 )
log "$ERROR"
fi
fi
}
log "$@"
# close or open?
close=$3
# check if we are on ac- or on battery-power
on_ac_power
if [ $? -ne 0 ]
then
# BATTERY
log "on battery power"
# suspend to ram
execute_command $SUSPEND
else
# AC
log "on AC power"
# switch-off screen
execute_command xsu "xset dpms force off"
fi
|
_________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Thu Jun 14, 2012 11:29 pm Post subject: |
|
|
I had to fix the script since the dynamic user detection failed under some circumstances.
The fixed version is now on github  _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Fri Jun 15, 2012 1:05 am Post subject: |
|
|
| M wrote: | | Code: | | XUSER=$(ps aux | grep [x]init | awk '{print $1}') |
|
or .. to not use any additional calls to grep ... or pipes.
| Code: | | XUSER=$(awk '$11 ~ /xinit/{print $1}' <(ps aux)) |
best ... khay |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Fri Jun 15, 2012 1:38 am Post subject: |
|
|
| Yminus wrote: | | Code: | [...]
home=$(grep $xuser /etc/passwd)
home=${home#*:*:*:*:*:}
home=${home%:*}
log "home is: $home"
[...] |
|
This just seems wasteful to me ... a suggestion:
| Code: | | home=$(awk -v user=${xuser} -F":" '{if ($1 == user) {print $6}}' /etc/passwd) |
best ... khay |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Fri Jun 15, 2012 8:29 am Post subject: |
|
|
| khayyam wrote: | | Yminus wrote: | | Code: | [...]
home=$(grep $xuser /etc/passwd)
home=${home#*:*:*:*:*:}
home=${home%:*}
log "home is: $home"
[...] |
|
This just seems wasteful to me ... a suggestion:
| Code: | | home=$(awk -v user=${xuser} -F":" '{if ($1 == user) {print $6}}' /etc/passwd) |
best ... khay |
Thanks for the suggestion. I have to admit that my 3 lines of code look cumbersome. But one could argue that calling awk is more wasteful than using bash builtins. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Fri Jun 15, 2012 9:04 am Post subject: |
|
|
| Yminus wrote: | | Thanks for the suggestion. I have to admit that my 3 lines of code look cumbersome. But one could argue that calling awk is more wasteful than using bash builtins. |
Your welcome ... but, no, your not simply using builtins, your calling grep. The awk does the equivelant task of grep plus extracts the value for var. Also, unlike grep awk doesn't parse the whole file for 'string', only the field, which in text parsing has greater economy.
but again ... just a suggestion
best ... khay |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Fri Jun 15, 2012 9:08 am Post subject: |
|
|
| khayyam wrote: | | ... but, no, your not simply using builtins, your calling grep. |
Oh, you're right - I have overlooked that. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Fri Jun 15, 2012 9:59 am Post subject: |
|
|
| Yminus wrote: | | Oh, you're right - I have overlooked that. |
Well, its not a big issue, but when trying to make something more economical often you want to avoid pipes and grep (which is guite greedy).
Also ... when you "fallback to static username", rather than do this make the initial assignment cover both possible values for var
| Code: | | xuser=${$(awk '$11 ~ /xinit/{print $1}' <(ps aux)):-${XUSER}} |
with this the subsequent test isn't necessary .. if 'xuser' is empty then the value of '${XUSER}' is used (though I would change the var names to something less confusing ... var1, var2 ... rather than case seperation).
best ...
khay |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Wed Jun 20, 2012 12:58 pm Post subject: |
|
|
| khayyam wrote: | | Yminus wrote: | | Code: | [...]
home=$(grep $xuser /etc/passwd)
home=${home#*:*:*:*:*:}
home=${home%:*}
log "home is: $home"
[...] |
|
This just seems wasteful to me ... a suggestion:
| Code: | | home=$(awk -v user=${xuser} -F":" '{if ($1 == user) {print $6}}' /etc/passwd) |
|
This seems like a good suggestions which I will adopt.
| khayyam wrote: | | Code: | | XUSER=$(awk '$11 ~ /xinit/{print $1}' <(ps aux)) |
|
As I already mentioned above this way of determine the X user does not work on my machine - I have no xinit process running.
But even if the above worked this one:
| Code: | | xuser=${$(awk '$11 ~ /xinit/{print $1}' <(ps aux)):-${XUSER}} |
would give a "bad substitution" error in bash. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Wed Jun 20, 2012 4:26 pm Post subject: |
|
|
| Yminus wrote: | | khayyam wrote: | | Code: | | XUSER=$(awk '$11 ~ /xinit/{print $1}' <(ps aux)) |
|
As I already mentioned above this way of determine the X user does not work on my machine - I have no xinit process running. |
OK .. but the 'who | sed' doesn't return anything either, which is the only reason I suggested using 'xinit'.
| Code: | % if [[ -z $(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p") ]] ; then echo 'the subsitution is empty!' ; fi
the subsitution is empty! |
The script "works" as it'll "fallback to static username", and so the asignment is essencially useless. So:
| Code: | | xuser=$(awk '{print $1}' <(who)) |
| Yminus wrote: | But even if the above worked this one:
| Code: | | xuser=${$(awk '$11 ~ /xinit/{print $1}' <(ps aux)):-${XUSER}} |
would give a "bad substitution" error in bash. |
hehe ... well too bad for bash, as the syntax is correct:
| Code: | % echo $SHELL
/bin/zsh
% echo $USERNAME
khayyam
% USERNAME=${$(awk '$11 ~ /xinit/{print $1}' <(ps aux)):-${USERNAME}}
% echo $USERNAME
khayyam
% exec bash -l
$ if [[ -z $USERNAME ]] ; then echo "USERNAME is empty" ; fi
USERNAME is empty
$ USERNAME=$(awk '$11 ~ /xinit/{print $1}' <(ps aux))
$ if [[ -n $USERNAME ]] ; then echo 'whats all this talk about "bad substitution"' ${USERNAME}'?' ; fi
whats all this talk about "bad substitution" khayyam?
$ export TEST_PARAM_EXPANSION=${TEST_PARAM_EXPANSION:-foo}
$ echo $TEST_PARAM_EXPANSION
foo
$ export TEST_PARAM_EXPANSION=${TEST_PARAM_EXPANSION:-ba}
$ echo $TEST_PARAM_EXPANSION
foo
$ export VAR=${$(echo ${TEST_PARAM_EXPANSION}):-ba}
bash: VAR=${$(echo ${TEST_PARAM_EXPANSION}):-ba}: bad substitution |
So, bash doesn't allow the use of a substitution within a parameter expansion .. doh! I guess with bash you have to go the extra mile:
| Code: | xuser=$(awk '$11 ~ /xinit/{print $1}' <(ps aux))
xuser=${xuser:-$XUSER} |
... and no obvious reason why.
best ... khay |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Wed Jun 20, 2012 7:52 pm Post subject: |
|
|
| khayyam wrote: | OK .. but the 'who | sed' doesn't return anything either, which is the only reason I suggested using 'xinit'.
| Code: | % if [[ -z $(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p") ]] ; then echo 'the subsitution is empty!' ; fi
the subsitution is empty! |
The script "works" as it'll "fallback to static username", and so the asignment is essencially useless.
|
That's not true - at least not on my machine. Here it returns the user that is logged in at the X-session, also in zsh. And the recent version of the regexp only reports the first occurrence of the user logged into X:
| Code: | echo "$(who | sed -ne "0,/^\([^ ]*\)[ ]*:0.*/s//\1/p")"
lars |
What is your output of who?
| khayyam wrote: | So:
| Code: | | xuser=$(awk '{print $1}' <(who)) |
|
Given this output of who:
| Code: | who
root tty1 2012-06-20 21:47
lars :0.0 2012-06-17 04:06
lars pts/0 2012-06-17 09:10 (:0.0)
lars pts/1 2012-06-20 10:30 (:0.0)
lars pts/2 2012-06-17 20:03 (:0.0)
lars pts/3 2012-06-20 11:17 (:0.0)
|
The above would return:
| Code: | awk '{print $1}' <(who)
root
lars
lars
lars
lars
lars
| or | Code: | echo $xuser
root lars lars lars lars lars |
This is not what I want. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Wed Jun 20, 2012 10:00 pm Post subject: |
|
|
| Yminus wrote: | | khayyam wrote: | OK .. but the 'who | sed' doesn't return anything either, which is the only reason I suggested using 'xinit'.
| Code: | % if [[ -z $(who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p") ]] ; then echo 'the subsitution is empty!' ; fi
the subsitution is empty! |
The script "works" as it'll "fallback to static username", and so the asignment is essencially useless. |
That's not true - at least not on my machine. Here it returns the user that is logged in at the X-session, also in zsh. And the recent version of the regexp only reports the first occurrence of the user logged into X:
| Code: | echo "$(who | sed -ne "0,/^\([^ ]*\)[ ]*:0.*/s//\1/p")"
lars |
What is your output of who? |
| Code: | % who
khayyam tty1 2012-06-20 20:12
% awk '/bin\/X/' <(ps aux)
root 1658 0.9 0.3 15176 7656 tty7 S<s+ 20:12 1:36 /usr/bin/X -nolisten tcp :0 -auth /home/khayyam/.serverauth.1640
% who | sed -ne "s/^\([^ ]*\)[ ]*:0.*/\1/p"
[EMPTY] |
As 'who' uses /var/log/wtmp it means that if something other than login writes to it then of course there will be confusion ... I suspect that either your terminal application is creating your shells as 'login shells' or your using 'screen' and it likewise isn't configure not to write to wtmp. Essencially you should only see one per tty (login), unless you explicitly create login shells ... 'who' has no relation to X11 sessions.
| Yminus wrote: | | khayyam wrote: | | Code: | | xuser=$(awk '{print $1}' <(who)) |
|
Given this output of who:
| Code: | who
root tty1 2012-06-20 21:47
lars :0.0 2012-06-17 04:06
lars pts/0 2012-06-17 09:10 (:0.0)
lars pts/1 2012-06-20 10:30 (:0.0)
lars pts/2 2012-06-17 20:03 (:0.0)
lars pts/3 2012-06-20 11:17 (:0.0)
|
The above would return:
| Code: | awk '{print $1}' <(who)
root
lars
lars
lars
lars
lars
|
This is not what I want. |
Agreed its not ideal ... but that's why I first opted for getting the user 'xuser' from xinit! The above is based on the assumption that only one user is logged in and so one string would be returned, but as 'who' simply dishes up whatevers in wtmp, it can't really be relied on. So the above "awk '{print $1}' <(who)" is as reliable as your 'who | sed'. We could make the awk more robust, but it doesn't really matter, because the input is from wtmp, and as you've seen, sometimes it'll fail ... sometimes not.
The only reliable method is to parse currently running processes, be that xinit or some other component of Xorg ...
best ... khay |
|
| Back to top |
|
 |
Yminus Tux's lil' helper

Joined: 06 Jan 2008 Posts: 144
|
Posted: Wed Jun 20, 2012 10:58 pm Post subject: |
|
|
Yes, this script works under the assumption that the login manager registers the user in the utmp/wtmp. For any other case there is the fallback.
I think to to parse currently running processes is not feasible since it differs to much from desktop to desktop. I guess even dbus won't work as a common denominator.
I could add the parsing for the xinit process as another alternative method - but I cannot test its reliability. _________________ Göögle is evil!
To protect your privacy search the net with
https://www.ixquick.com |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Thu Jun 21, 2012 12:23 am Post subject: |
|
|
Well, ppurka's post is re window-managers and not login managers, the formers should not need to write to wtmp, and the later only if sees to it that its removed at logout. Anyhow, regardless, relying on wtmp is hit or miss.
| Yminus wrote: | | For any other case there is the fallback. |
OK, but if setting a var you remove the whole need (and purpose) of any auto asignment. I wouldn't have a fallback at all, I'd have it fail, but only after all possible methods have been exhausted.
| Yminus wrote: | | I think to to parse currently running processes is not feasible since it differs to much from desktop to desktop. I guess even dbus won't work as a common denominator. |
Well, I would say they will all be running X11 and so that is a common denominator, its going to more consistant than 'who'. If I examine my own processes I can see two methods of grabbing xuser, the first xinit, and the second via the xauthority string. Neither of these may be consistant with your currently running X11 session (I assume using a login manager), but this doesn't matter because you can test until the var has some value.
| Yminus wrote: | | I could add the parsing for the xinit process as another alternative method - but I cannot test its reliability. |
You don't need to, all you need do is add additional tests for the two common methods of starting an X11 session, 1). via startx/xinit, and 2). via a login manager. One or other of these should return a value (but again using wtmp will be unreliable).
Anyhow ... my inital reason for getting started in this thread was simply to point out some areas where code could be optimised, and now I feel I'm having to justify having comented at all, and explain why bash, or awk, do what they do ... and so I'll bow out ...
best ... khay |
|
| Back to top |
|
 |
ppurka Advocate

Joined: 26 Dec 2004 Posts: 3067
|
Posted: Thu Jun 21, 2012 12:54 am Post subject: |
|
|
| khayyam wrote: |
Well, ppurka's post is re window-managers and not login managers, the formers should not need to write to wtmp, and the later only if sees to it that its removed at logout. Anyhow, regardless, relying on wtmp is hit or miss. | No, my post was with regard to login managers. Login managers should update the utmp/wtmp on successful login. They have always done so.
And lightdm is one of the newfangled half-done login managers which doesn't write to utmp/wtmp. And yet you see it being used in popular distros nowadays. It just seems like apathy of the devs, who don't care about supporting traditional *nix methods. _________________ emerge --quiet redefined | E17 vids: I, II |
|
| Back to top |
|
 |
khayyam Veteran


Joined: 07 Jun 2012 Posts: 1307
|
Posted: Thu Jun 21, 2012 6:39 am Post subject: |
|
|
| ppurka wrote: | | No, my post was with regard to login managers. Login managers should update the utmp/wtmp on successful login. They have always done so. |
I stand corrected ...
best ... khay |
|
| Back to top |
|
 |
|