You are not logged in.
Hi,
I have installed udev-media-automount (recommended on Arch Wiki) to auto-mount my external drives through udev. It's working perfectly, I even "improved" it with a notification showing up when a drive gets mounted.
That notification took quite a bit of research as DBUS_SESSION_BUS_ADDRESS wasn't so easy to figure out:
DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $username)/bus runuser -u user notify-send "$dev > $AUTOMOUNT_DIR"Now I got an idea. It would be great to open a terminal emulator (using "st") automatically and cd into the external drive. That's even better than just a notification.
However, all my attempts to do so have failed, I haven't found a way to launch "st" from a background script as root, but run "st" as a non-root user:
# DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user 'st -e cd /media/mounted_drive'
runuser: failed to execute st -e cd /media/mounted_drive: No such file or directoryThen there is another question: how would you ensure that the terminal emulator stays open? Doing:
while true; do
sleep 10
donewould make the emulator unusable.
Is this even possible? Thanks!
Last edited by goldmund (2022-01-29 15:19:22)
Offline
https://gist.github.com/AladW/de1c5676d93d05a5a0e1
type cd will tell you that this is a shell built-in. What you actually want to do is (I guess) to run an interactive shell and start that at the desired directory.
Try sth. like
# cd /media/mounted_drive
# DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user stOffline
https://gist.github.com/AladW/de1c5676d93d05a5a0e1
type cdwill tell you that this is a shell built-in. What you actually want to do is (I guess) to run an interactive shell and start that at the desired directory.
Try sth. like# cd /media/mounted_drive # DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user st
True! Should have thought of that before.
Unfortunately, st is now complaining that it:
can't open display(despite DISPLAY=:0 being set)
Offline
runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st?
(idk at hand what environment runuser nukes, so …)
Offline
runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st?
(idk at hand what environment runuser nukes, so …)
Okay, this is weird. It's still saying the same:
# runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st
can't open displayWhen changing DISPLAY=:0 to DISPLAY=:1 it does:
Authorization required, but no authorization protocol specified
can't open displayI've tried DISPLAY=:1 because:
$ echo $DISPLAY
:1Last edited by goldmund (2022-01-28 16:36:20)
Offline
GDM?
loginctl session-statusSee the link in #2 for the XAUTHORITY variable.
Offline
Sorry, that code seems to me a little cryptic, I've tried hard, but don't understand it. GDM? You mean Gnome Display Manager? I am not running gnome, but dwm, and don't have a display manager.
Perhaps I should mention that I am not using xinit, but sx.
Offline
You can use that script, but instead of the "xinit" process you look for the "sx" process.
It will assign the variables properly and you can then pass them to runuser via the "-w" parameter.
Offline
You can use that script, but instead of the "xinit" process you look for the "sx" process.
It will assign the variables properly and you can then pass them to runuser via the "-w" parameter.
Sorry for being so dumb, I am giving you a hard time.
So I put that into my script:
pid=$(pgrep -t tty$(fgconsole) sx)
pid=$(pgrep -P $pid -n)
import_environment() {
(( pid )) && for var; do
IFS='=' read key val < <(egrep -z "$var" /proc/$pid/environ)
printf -v "$key" %s "$val"
[[ ${!key} ]] && export "$key"
done
}
import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY
runuser -u user -w DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY stbut st is still complaining:
can't open displayThe above mentioned variables are not even set!
BTW, this doesn't seem to work:
$ pid=$(pgrep -t tty1 sx)
$ pgrep -P "$pid" -n
pgrep: not a number: 1035
1080
1087
1091
1092
1094
1099
(exit code 1)What am I doing wrong?
Offline
"pgrep sx" matches too many processes
pid=$(pgrep -t tty$(fgconsole) "/usr/bin/sx")Also the commas have no business being in
import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITYOffline
"pgrep sx" matches too many processes
pid=$(pgrep -t tty$(fgconsole) "/usr/bin/sx")Also the commas have no business being in
import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY
Perfect, this works! A terminal window now opens when an external drive is mounted. Thank you!
Strangely,
pgrep -t tty$(fgconsole) "/usr/bin/sx"doesn't output anything, despite the fact that:
$ which sx
/usr/bin/sxI had to do
pgrep -t tty$(fgconsole) sx | head -n1for it to output a pid.
Offline
pgrep must be reflected in "ps aux | grep sx" - I took "/usr/bin/sx" from your earlier "loginctl session-status"
You basically just have to isolate a process that's running for the current/desired user to import the environment from there.
Please always remember to mark resolved threads by editing your initial posts subject - so others will know that there's no task left, but maybe a solution to find.
Thanks.
Offline
Great, thanks again!
Offline
We'll handle this on the forum ;-)
There is just a small problem which annoys me: when the terminal window opens, I issue some commands and after a while I forget that this specific terminal was launched from the background script. When
I eventually decide to unmount the drive, umount is complaining that "target is busy", despite the fact that I have cd-ed outside the mounted directory a long time ago. Then I have to figure out which
terminal was launched from the background script (sometimes I have LOTS of terminal emulators open) and close it. Only then does umount allow me to unmount the drive.I was wondering if there was a way to daemonize the launch of the terminal and break any connection to the background script, I have tried for example setsid:
cd "$AUTOMOUNT_DIR"
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- setsid -f /usr/local/bin/st
cd /But that doesn't change a thing.
The trailing "cd /" won't be reached but simply forking the runuser (add a trailing "&") should™ do (because then the script continues and exits and doesn't keep the path active)
Offline
The trailing "cd /" won't be reached but simply forking the runuser (add a trailing "&") should™ do (because then the script continues and exits and doesn't keep the path active)
I've tried that, however, none of this helps:
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY /usr/local/bin/st &
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY '/usr/local/bin/st' &
setsid -f runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY '/usr/local/bin/st'
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- setsid -f '/usr/local/bin/st'I still have to close the terminal in order to unmount the drive. I don't have any other idea, do you?
Offline
You'll then have to go for https://bbs.archlinux.org/viewtopic.php … 3#p2009943
Offline
Hm, launching bash is also not helping:
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- st -e bashI don't have .bashrc, because I am using zsh; I've only tried this to see if it worked. Launching zsh also doesn't work.
Offline
The trick there was to create a transient copy of the bashrc that trails a command (in your case "cd somewhere") - something that afaics won't work w/ zsh
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- st -e env -C /media/mounted_drive zshmight.
Offline
I've tried that, unfortunately it doesn't work either.
I just got the idea that I could launch a terminal and cd into the drive with xdotool. It's quite dirty, but it would work. Or just abandon the idea altogether...
Offline
Doesn't work like "doesn't allow me to umount the drive w/o closing the terminal"? Could be, because the zsh process itself has still the wrong PWD.
If you're willign to touch your zshrc for this you could export some variable like "export ZSH_START_DIR=/media/mounted_drive" and in your zshrc test that variable and cd there.
[ -n $ZSH_START_DIR ] && cd $ZSH_START_DIROffline
This works fantastic! What a great idea and how simple! Thank you!!!
Offline
You also want to quote the variable and tail "unset ZSH_START_DIR" to prevent it from leaking into subshells and causing unpleasant surprises.
[ -n "$ZSH_START_DIR "] && cd "$ZSH_START_DIR"; unset ZSH_START_DIRAbout your latest DM: if you desperately want to donate some *really* expendable income, see https://archlinux.org/donate/ and you can also purchase merchandise, https://archlinux.org/
But I want to make clear that you're not oblieged to and you don't owe me anything - so don't touch goldmund jr.'s birthday fund ![]()
Offline
You also want to quote the variable and tail "unset ZSH_START_DIR" to prevent it from leaking into subshells and causing unpleasant surprises.
[ -n "$ZSH_START_DIR "] && cd "$ZSH_START_DIR"; unset ZSH_START_DIR
Good idea, thanks!
About your latest DM: if you desperately want to donate some *really* expendable income, see https://archlinux.org/donate/ and you can also purchase merchandise, https://archlinux.org/
But I want to make clear that you're not oblieged to and you don't owe me anything - so don't touch goldmund jr.'s birthday fund
Your selflessness is incredible! I am going to donate to Arch Linux.
Offline